--- /dev/null
+diff --git a/nemo-api/src/main/yang/nemo-common.yang b/nemo-api/src/main/yang/nemo-common.yang
+index cbccc32..072745f 100644
+--- a/nemo-api/src/main/yang/nemo-common.yang
++++ b/nemo-api/src/main/yang/nemo-common.yang
+@@ -1,32 +1,37 @@
+ /*\r
+- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
++ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+ \r
+-module nemo-common{\r
+- yang-version 1; \r
+- namespace "urn:opendaylight:params:xml:ns:yang:nemo:common"; \r
+- prefix "nemo-common";\r
+- \r
+- revision "2015-06-29" {\r
++module nemo-common {\r
++ yang-version 1;\r
++\r
++ namespace "urn:opendaylight:params:xml:ns:yang:nemo:common";\r
++ prefix "nemo-common";\r
++\r
++ description\r
++ "Common types and definitions for NEMO models";\r
++\r
++ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+- \r
+- /**********************\r
+- * Base types\r
+- **********************/\r
+- typedef description {\r
+- description "A human-readable description for a object.";\r
++\r
++ // *********************\r
++ // * Base Types\r
++ // *********************\r
++ typedef description {\r
++ description\r
++ "A human-readable description for a object.";\r
+ type string {\r
+ length "1..4096";\r
+ }\r
+ }\r
+- \r
+- typedef name {\r
++\r
++ typedef name {\r
+ description\r
+ "A generic string name type. Must start with a letter";\r
+ type string {\r
+@@ -34,8 +39,8 @@ module nemo-common{
+ length "1..256";\r
+ }\r
+ }\r
+- \r
+- // UUID type from ietf-yang-types@2013-07-15\r
++\r
++ // UUID type from ietf-yang-types@2013-07-15\r
+ typedef uuid {\r
+ type string {\r
+ pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'\r
+@@ -43,8 +48,8 @@ module nemo-common{
+ }\r
+ description\r
+ "A Universally Unique IDentifier in the string representation\r
+- defined in RFC 4122. The canonical representation uses\r
+- lowercase characters.\r
++ defined in RFC 4122. The canonical representation uses\r
++ lower case characters.\r
+ \r
+ The following is an example of a UUID in string\r
+ representation: f81d4fae-7dec-11d0-a765-00a0c91e6bf6";\r
+@@ -54,265 +59,179 @@ module nemo-common{
+ }\r
+ \r
+ typedef unique-id {\r
++ description\r
++ "A globally unique identifier.";\r
+ type uuid;\r
+- description "A globally unique identifier";\r
+ }\r
+- \r
+- /*********************\r
+- * Unique IDs\r
+- *********************/ \r
+- typedef object-id {\r
++\r
++ // *********************\r
++ // * Unique IDs\r
++ // *********************\r
++ typedef object-id {\r
++ description\r
++ "A unique ID for a parameterized object.";\r
+ type unique-id;\r
+- description "A unique ID for a parameterized object";\r
+ }\r
+- \r
+- typedef node-definition-id {\r
+- type object-id;\r
+- description "A unique ID for a node definition.";\r
+- }\r
+- typedef node-instance-id {\r
+- type object-id;\r
+- description "A unique ID for a node instance.";\r
+- } \r
+- \r
+- typedef connection-definition-id {\r
++\r
++ typedef node-id {\r
++ description\r
++ "A unique ID for a node.";\r
+ type object-id;\r
+- description "A unique ID for a connection definition.";\r
+ }\r
+- typedef connection-instance-id {\r
+- type object-id;\r
+- description "A unique ID for a connection instance.";\r
+- } \r
+- \r
+- typedef flow-definition-id {\r
++\r
++ typedef connection-id {\r
++ description\r
++ "A unique ID for a connection.";\r
+ type object-id;\r
+- description "A unique ID for a flow definition.";\r
+ }\r
+- typedef flow-instance-id {\r
++\r
++ typedef flow-id {\r
++ description\r
++ "A unique ID for a flow.";\r
+ type object-id;\r
+- description "A unique ID for a flow instance.";\r
+ }\r
+- \r
+- typedef expected-definition-id {\r
++\r
++ typedef intent-id {\r
++ description\r
++ "A unique ID for an intent.";\r
+ type unique-id;\r
+- description "A unique ID for an expected definition.";\r
+ }\r
+- typedef expected-instance-id {\r
++\r
++ typedef user-id {\r
++ description\r
++ "A unique ID for a user.";\r
+ type unique-id;\r
+- description "A unique ID for an expected instance.";\r
+ }\r
+- \r
+- typedef avoid-definition-id {\r
++\r
++ typedef operation-id {\r
++ description\r
++ "A unique ID for an operation.";\r
+ type unique-id;\r
+- description "A unique ID for an avoid definition.";\r
+ }\r
+- typedef avoid-instance-id {\r
+- type unique-id;\r
+- description "A unique ID for an avoid instance.";\r
+- }\r
+- \r
+- typedef context-id {\r
+- type unique-id;\r
+- description "A unique ID for a context.";\r
+- }\r
+- \r
+- typedef intent-id {\r
++\r
++ typedef condition-segment-id {\r
++ description\r
++ "A unique ID for a segment of the condition in an operation.";\r
+ type unique-id;\r
+- description "A unique ID for an intent.";\r
+ }\r
+- \r
+- typedef user-id {\r
++\r
++ typedef query-condition-id {\r
++ description\r
++ "A unique ID for a condition of the advanced query.";\r
+ type unique-id;\r
+- description "A unique ID for a user.";\r
+- }\r
+- \r
+- \r
+- \r
+- /*********************\r
+- * names\r
+- *********************/ \r
+- typedef object-name {\r
++ }\r
++\r
++ // *********************\r
++ // * Names\r
++ // *********************\r
++ typedef object-name {\r
++ description\r
++ "A name for a parameterized object";\r
+ type name;\r
+- description "A name for a parameterized object";\r
+ }\r
+- \r
+- typedef node-instance-name {\r
++\r
++ typedef node-name {\r
++ description\r
++ "A name for a node instance.";\r
+ type object-name;\r
+- description "A name for a node instance.";\r
+- } \r
+- \r
+- typedef connection-instance-name {\r
++ }\r
++\r
++ typedef connection-name {\r
++ description\r
++ "A name for a connection instance.";\r
+ type object-name;\r
+- description "A name for a connection instance.";\r
+- } \r
+- \r
+- typedef flow-instance-name {\r
++ }\r
++\r
++ typedef flow-name {\r
++ description\r
++ "A name for a flow instance.";\r
+ type object-name;\r
+- description "A name for a flow instance.";\r
+- } \r
+- \r
+- typedef node-property-name {\r
+- type name;\r
+- description "A name for a node property.";\r
+- } \r
+- \r
+- typedef connection-property-name {\r
++ }\r
++\r
++ typedef match-item-name {\r
++ description\r
++ "A name for a match item.";\r
+ type name;\r
+- description "A name for a connection property.";\r
+- } \r
++ }\r
+ \r
+- typedef match-item-name {\r
++ typedef property-name {\r
++ description\r
++ "A name for a property.";\r
+ type name;\r
+- description "A name for a flow match item.";\r
+ }\r
+- \r
+- typedef property-name {\r
++\r
++ typedef parameter-name {\r
++ description\r
++ "A name for a parameter.";\r
+ type name;\r
+- description "A name for a property.";\r
+ }\r
+- \r
+- typedef parameter-name {\r
++\r
++ typedef action-name {\r
++ description\r
++ "A name for an action.";\r
+ type name;\r
+- description "A name for a parameter.";\r
+ }\r
+- \r
+- typedef action-definition-name {\r
++\r
++ typedef condition-parameter-name {\r
++ description\r
++ "A name for a parameter of condition.";\r
+ type name;\r
+- description "A name for an action definition.";\r
+- } \r
+- typedef action-instance-name {\r
++ }\r
++\r
++ typedef user-name {\r
++ description\r
++ "A name for a user.";\r
+ type name;\r
+- description "A name for an action instance.";\r
+- } \r
+- typedef condition-definition-name {\r
++ }\r
++\r
++ typedef user-password {\r
++ description\r
++ "A password for a user.";\r
+ type name;\r
+- description "A name for a condition definition.";\r
+- }\r
+- typedef condition-instance-name {\r
+- type name;\r
+- description "A name for a condition instance.";\r
+- }\r
+- typedef condition-parameter-name {\r
+- type name;\r
+- description "A name for a condition parameter.";\r
+- }\r
+- typedef constraint-definition-name {\r
++ }\r
++\r
++ typedef operation-name {\r
++ description\r
++ "A name for an operation.";\r
+ type name;\r
+- description "A name for a constraint definition.";\r
+- }\r
+- typedef constraint-instance-name {\r
+- type name;\r
+- description "A name for a constraint instance.";\r
+- }\r
+- typedef constraint-parameter-name {\r
+- type name;\r
+- description "A name for a constraint parameter.";\r
+- }\r
+- \r
+-\r
+- typedef data-name {\r
+- type name;\r
+- description "A name for an action data.";\r
+- }\r
+- \r
+- typedef context-name {\r
+- type name;\r
+- description "A name for an context";\r
+- }\r
+- \r
+- typedef intent-name {\r
++ }\r
++\r
++ typedef query-condition-name {\r
++ description\r
++ "A name for a query with condition.";\r
+ type name;\r
+- description "A name for an intent.";\r
+ }\r
+- typedef user-name {\r
++\r
++ typedef user-role-name {\r
++ description\r
++ "A role name for a user.";\r
+ type name;\r
+- description "A name for a user.";\r
+ }\r
+- typedef expected-instance-name {\r
++\r
++ typedef user-role-description {\r
++ description\r
++ "It describes the role characteristic and responsibility range.";\r
++ type string;\r
++ }\r
++\r
++ // *********************\r
++ // * Types\r
++ // *********************\r
++ typedef node-type {\r
++ description\r
++ "The type for a node.";\r
+ type name;\r
+- description "A name for an expected instance.";\r
+ }\r
+- typedef avoid-instance-name {\r
++\r
++ typedef connection-type {\r
++ description\r
++ "The type for a connection.";\r
+ type name;\r
+- description "A name for an avoid instance.";\r
+- }\r
+- \r
+- \r
+- \r
+- /*********************\r
+- * types\r
+- *********************/ \r
+- typedef node-definition-type {\r
+- type name;\r
+- description "A type for a node."; \r
+- }\r
+- typedef connection-definition-type {\r
+- type name;\r
+- description "A type for a connection."; \r
+- }\r
+- typedef flow-definition-type {\r
+- type name;\r
+- description "A type for a flow."; \r
+- } \r
+- typedef node-instance-type {\r
+- type name;\r
+- description "A type for a node instance."; \r
+- } \r
+- typedef connection-instance-type {\r
+- type name;\r
+- description "A type for a connection instance."; \r
+- }\r
+- typedef flow-instance-type {\r
+- type name;\r
+- description "A type for a flow instance."; \r
+- }\r
++ }\r
+ \r
++ typedef flow-type {\r
++ description\r
++ "The type for a flow.";\r
++ type name;\r
++ }\r
+ }\r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+- \r
+-
+\ No newline at end of file
+diff --git a/nemo-api/src/main/yang/nemo-intent.yang b/nemo-api/src/main/yang/nemo-intent.yang
+index 21760a0..91876aa 100644
+--- a/nemo-api/src/main/yang/nemo-intent.yang
++++ b/nemo-api/src/main/yang/nemo-intent.yang
+@@ -1,136 +1,395 @@
+ /*\r
+- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
++ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+- \r
++\r
+ module nemo-intent {\r
+- yang-version 1; \r
+- namespace "urn:opendaylight:params:xml:ns:yang:nemo:intent"; \r
+- prefix "nemo-intent";\r
+- \r
+- import nemo-common {prefix nemo-common;}\r
+- import nemo-object {prefix nemo-object;}\r
+- import nemo-operation {prefix nemo-operation;}\r
+- import nemo-result {prefix nemo-result;}\r
+- \r
+- revision "2015-06-29" {\r
++ yang-version 1;\r
++\r
++ namespace "urn:opendaylight:params:xml:ns:yang:nemo:intent";\r
++ prefix "nemo-intent";\r
++\r
++ import nemo-common {prefix nemo-common;}\r
++ import nemo-object {prefix nemo-object;}\r
++ import nemo-operation {prefix nemo-operation;}\r
++ import nemo-user {prefix nemo-user;}\r
++\r
++ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+- \r
+- grouping intent-instance {\r
+- description "";\r
+- leaf intent-id {\r
+- description "A unique ID for the intent";\r
+- type nemo-common:intent-id; \r
+- mandatory true;\r
+- } \r
+- leaf intent-name {\r
+- description "A user-visible name for the intent";\r
+- type nemo-common:intent-name;\r
+- } \r
+- container objects {\r
+- description "";\r
+- list node {\r
+- key "node-id";\r
+- uses nemo-object:node-instance;\r
+- } \r
+- list connection {\r
+- key "connection-id";\r
+- uses nemo-object:connection-instance;\r
+- } \r
+- list flow {\r
+- key "flow-id";\r
+- uses nemo-object:flow-instance;\r
+- } \r
+- }\r
+- \r
+- container operation {\r
+- leaf apply-on-object {\r
+- type nemo-common:object-id;\r
+- mandatory true;\r
+- } \r
+- leaf priority{\r
+- type int64;\r
+- default 1;\r
+- }\r
+- uses nemo-operation:condition-instance;\r
+- uses nemo-operation:action-instance;\r
+- uses nemo-operation:constraint-instance; \r
+- }\r
+- \r
+- container result{\r
+- leaf result-to-object {\r
+- type nemo-common:object-id;\r
+- mandatory true;\r
+- } \r
+- leaf priority{\r
+- type int64;\r
+- default 1;\r
+- }\r
+- choice result-mode {\r
+- mandatory true;\r
+- case expected-case {\r
+- uses nemo-result:expected-instance;\r
+- }\r
+- case avoid-case{\r
+- uses nemo-result:avoid-instance;\r
+- } \r
+- } \r
+- } \r
+- container contexts{\r
+- list context {\r
+- key "context-id";\r
+- leaf context-id {\r
+- type nemo-common:context-id;\r
+- mandatory true;\r
+- }\r
+- leaf context-name{\r
+- type nemo-common:context-name;\r
+- mandatory true;\r
+- }\r
+- } \r
+- }\r
+- }\r
+- \r
+- container users {\r
+- description "The list of all known users";\r
+- list user {\r
+- description "";\r
++\r
++ grouping user-intent {\r
++ description\r
++ "User intent refers to a purpose in getting an ultimate result\r
++ or performing some specific operation on some objects.";\r
++\r
++ container objects {\r
++ description\r
++ "The element could be operated and managed by users.\r
++ It inludes resources to construct users' virtual network,\r
++ and the services in this network.In NEMO project, it is\r
++ abstracted into node, connection and flow";\r
++\r
++ list node {\r
++ key "node-id";\r
++ uses nemo-object:node-instance;\r
++ }\r
++\r
++ list connection {\r
++ key "connection-id";\r
++ uses nemo-object:connection-instance;\r
++ }\r
++\r
++ list flow {\r
++ key "flow-id";\r
++ uses nemo-object:flow-instance;\r
++ }\r
++ }\r
++\r
++ container operations {\r
++ description\r
++ "The operation is to dynamically adjust the behavior of network,\r
++ and it is applied on objects, that is, node, connection and flow";\r
++\r
++ list operation {\r
++ key "operation-id";\r
++ uses nemo-operation:operation-instance;\r
++ }\r
++ }\r
++\r
++ container results {\r
++ // TBD\r
++ }\r
++ }\r
++\r
++ container users {\r
++ description\r
++ "The list of all known users";\r
++\r
++ list user {\r
++ description\r
++ "A user is an administrative domain which is\r
++ logically separated from other users, and each\r
++ intent is specified by a particular user.";\r
++\r
+ key "user-id";\r
+- leaf user-id {\r
+- description "A unique ID for the user"; \r
+- type nemo-common:user-id;\r
+- mandatory true;\r
+- }\r
+- leaf user-name {\r
+- description "A user-visible name for the user";\r
+- type nemo-common:user-name;\r
+- mandatory false;\r
+- } \r
+- list intent{\r
+- key "intent-id";\r
+- uses intent-instance;\r
+- min-elements 1;\r
+- }\r
+- } \r
+- }\r
+- \r
+- rpc register-node-instance {\r
+- description "";\r
+- input {\r
+- uses nemo-object:node-instance;\r
+- }\r
+- }\r
+- \r
+- rpc unregister-node-instance {\r
+- description "";\r
+- input {\r
+- uses nemo-object:node-instance;\r
+- }\r
+- }\r
+- \r
+-}
+\ No newline at end of file
++ uses nemo-user:user-instance;\r
++ uses user-intent;\r
++ }\r
++ }\r
++\r
++ container query-condition-definitions {\r
++ description\r
++ "Contains the definitions for all advanced query, which means\r
++ they are the query with conditions supported by the NEMO engine.\r
++ User will fetch all results which meet the condition.";\r
++\r
++ list query-condition-definition {\r
++ description\r
++ "Define the query with condition. For example, user may\r
++ intent to query all connection's name whose utilization is\r
++ beyond 80%. That is a query with condition.";\r
++\r
++ key "query-condition-name query-intent-type";\r
++ leaf query-condition-name {\r
++ description\r
++ "A user-visible name for the query condition definition.\r
++ The query condition name is usually to specify the\r
++ attribute or property of some kind of intent.\r
++ For the above example, the query-condition-name is utility.";\r
++ type nemo-common:query-condition-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf query-intent-type {\r
++ description\r
++ "The target for the query, and its attributes will be checked out\r
++ if meet the condition. In the above example, connection is the\r
++ target. So, connection will be the query-intent-type here.";\r
++ type enumeration {\r
++ enum node;\r
++ enum connection;\r
++ enum flow;\r
++ enum operation;\r
++ enum result;\r
++ }\r
++ }\r
++\r
++ leaf query-condition-value-type {\r
++ description\r
++ "The type of the target value for the query condition.\r
++ For the above example, the target-value is 80(%),\r
++ so the query-condition-value-type will be int.";\r
++ default string;\r
++ type enumeration {\r
++ enum string {\r
++ description\r
++ "A string-valued target value.";\r
++ }\r
++ enum int {\r
++ description\r
++ "An integer-valued target value.";\r
++ }\r
++ enum range {\r
++ description\r
++ "An integer-range target value.";\r
++ }\r
++ }\r
++ }\r
++\r
++ container query-condition-match-patterns {\r
++ description\r
++ "The relationship between the value of query-condition-name\r
++ and query-condition-target-value. If an intent's attribute\r
++ or property specified by the query condition name matches\r
++ to the target value by the match pattern, this intent meets\r
++ the condition. For the above example, the condition's\r
++ query-condition-match-patterns could be less-than, not-less-than,\r
++ equal, not-equal, greater-than, not-greater-than, between.";\r
++\r
++ leaf-list query-condition-match-pattern {\r
++ type enumeration {\r
++ enum less-than;\r
++ enum not-less-than;\r
++ enum equal;\r
++ enum not-equal;\r
++ enum greater-than;\r
++ enum not-greater-than;\r
++ enum between;\r
++ }\r
++ }\r
++ }\r
++ }\r
++ }\r
++\r
++ grouping common-rpc-result {\r
++ description\r
++ "Common return result for all defined RPCs.";\r
++\r
++ leaf result-code {\r
++ description\r
++ "Result code which is convenient for processing in a program.";\r
++ type enumeration {\r
++ enum ok {\r
++ description\r
++ "The invoked RPC was executed successfully";\r
++ }\r
++ enum error {\r
++ description\r
++ "There's an error while executing the RPC";\r
++ }\r
++ }\r
++ }\r
++\r
++ leaf message {\r
++ description\r
++ "A human-readable message for an error or exception";\r
++ type string;\r
++ }\r
++ }\r
++\r
++ grouping query-condition-instance {\r
++ description\r
++ "A query condition instance generated according to\r
++ a specified query condition definition.";\r
++\r
++ leaf query-condition-id {\r
++ description\r
++ "A unique ID for a query condition instance.";\r
++ type nemo-common:query-condition-id;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf query-condition-name {\r
++ description\r
++ "The name of the query condition definition.";\r
++ type nemo-common:query-condition-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf query-intent-type {\r
++ description\r
++ "The type of the intents that the user wants to query from through\r
++ the condition instance.";\r
++ type enumeration {\r
++ enum node;\r
++ enum connection;\r
++ enum flow;\r
++ enum operation;\r
++ enum result;\r
++ }\r
++ }\r
++\r
++ leaf query-condition-match-pattern {\r
++ description\r
++ "The match pattern the condition instance will use.";\r
++ type enumeration {\r
++ enum less-than;\r
++ enum not-less-than;\r
++ enum equal;\r
++ enum not-equal;\r
++ enum greater-than;\r
++ enum not-greater-than;\r
++ enum between;\r
++ }\r
++ }\r
++\r
++ container query-condition-target-value {\r
++ description\r
++ "The target value used to compare with the attribute\r
++ or property of the intents.";\r
++\r
++ leaf string-value {\r
++ type string;\r
++ }\r
++\r
++ leaf int-value {\r
++ type int64;\r
++ }\r
++\r
++ container range-value {\r
++ leaf min {\r
++ type int64;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf max {\r
++ type int64;\r
++ mandatory true;\r
++ }\r
++ }\r
++ }\r
++ }\r
++\r
++ rpc register-user {\r
++ description\r
++ "Register a user to the user repository.";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ }\r
++ }\r
++\r
++ rpc begin-transaction {\r
++ description\r
++ "Begin a transaction for the user";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ }\r
++ }\r
++\r
++ rpc end-transaction {\r
++ description\r
++ "Commit the user's current transaction";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ }\r
++ }\r
++\r
++ rpc language-style-nemo-request {\r
++ description\r
++ "Create, update or delete an intent of a user through an NEMO statement";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++\r
++ leaf nemo-statement {\r
++ type string;\r
++ }\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ }\r
++ }\r
++\r
++ rpc structure-style-nemo-update {\r
++ description\r
++ "Create or update all or a part of the user's intents,\r
++ which are described as json or xml format.";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++ uses user-intent;\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ }\r
++ }\r
++\r
++ rpc structure-style-nemo-delete {\r
++ description\r
++ "Delete some intents of a user from the user repository";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++\r
++ container objects {\r
++ leaf-list node {\r
++ type nemo-common:node-id;\r
++ }\r
++\r
++ leaf-list connection {\r
++ type nemo-common:connection-id;\r
++ }\r
++\r
++ leaf-list flow {\r
++ type nemo-common:flow-id;\r
++ }\r
++ }\r
++\r
++ container operations {\r
++ leaf-list operation {\r
++ type nemo-common:operation-id;\r
++ }\r
++ }\r
++\r
++ container results {\r
++ // TBD\r
++ }\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ }\r
++ }\r
++\r
++ rpc advanced-nemo-query {\r
++ description\r
++ "Query some intents of a user from the user repository\r
++ according to several advanced query conditions.";\r
++\r
++ input {\r
++ uses nemo-user:user-instance;\r
++\r
++ list query-condition {\r
++ key "query-condition-id";\r
++ uses query-condition-instance;\r
++ }\r
++ }\r
++\r
++ output {\r
++ uses common-rpc-result;\r
++ uses user-intent;\r
++ }\r
++ }\r
++}\r
+diff --git a/nemo-api/src/main/yang/nemo-object.yang b/nemo-api/src/main/yang/nemo-object.yang
+index 30500fd..347406d 100644
+--- a/nemo-api/src/main/yang/nemo-object.yang
++++ b/nemo-api/src/main/yang/nemo-object.yang
+@@ -1,331 +1,405 @@
+ /*\r
+- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
++ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+ \r
+-module nemo-object{\r
+- yang-version 1; \r
+- namespace "urn:opendaylight:params:xml:ns:yang:nemo:object"; \r
+- prefix "nemo-object";\r
+- \r
+- import nemo-common {prefix nemo-common;}\r
+- \r
+- revision "2015-06-29" {\r
++module nemo-object {\r
++ yang-version 1;\r
++\r
++ namespace "urn:opendaylight:params:xml:ns:yang:nemo:object";\r
++ prefix "nemo-object";\r
++\r
++ import nemo-common {prefix nemo-common;}\r
++\r
++ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+- \r
+- grouping property-definition { \r
+- list property {\r
+- description "";\r
+- key "name";\r
+- leaf name {\r
+- description "A user-visible name for the property";\r
++\r
++ grouping property-definitions {\r
++ list property-definition {\r
++ description\r
++ "The property definitions for the type of node or connection.";\r
++\r
++ key "property-name";\r
++ leaf property-name {\r
++ description\r
++ "A user-visible and unique name for the property.";\r
+ type nemo-common:property-name;\r
+ mandatory true;\r
+ }\r
+- leaf value-type {\r
+- description "The type of the property";\r
++\r
++ leaf property-value-type {\r
++ description\r
++ "The type of the property value.";\r
+ default string;\r
+ type enumeration {\r
+ enum string {\r
+- description "A string-valued property";\r
++ description\r
++ "An string-valued property.";\r
+ }\r
+ enum int {\r
+- description "An integer-valued property";\r
++ description\r
++ "An integer-valued property.";\r
+ }\r
+ enum range {\r
+- description "An integer-range property";\r
++ description\r
++ "An integer-range property.";\r
+ }\r
+ }\r
+ }\r
++\r
+ leaf is-required {\r
+- description "Specify whether the property is\r
+- required for object.";\r
++ description\r
++ "Specify whether the property is required for the object.";\r
+ default optional;\r
+ type enumeration {\r
+ enum required {\r
+- description "The property is required";\r
++ description\r
++ "The property is required";\r
+ }\r
+ enum optional {\r
+- description "The property is optional";\r
++ description\r
++ "The property is optional";\r
+ }\r
+ }\r
+ }\r
+- } \r
+- } \r
+- container node-definitions{\r
+- list node-definition{\r
+- description "";\r
+- key "id";\r
+- leaf id {\r
+- description "A unique ID for a kind of node definition";\r
+- type nemo-common:node-definition-id;\r
+- mandatory true;\r
+- } \r
+- leaf node-type{\r
+- description "A user-readable description";\r
+- type nemo-common:node-definition-type;\r
+- mandatory true; \r
+- }\r
+- uses property-definition; \r
+- } \r
+- } \r
+- container connection-definitions{\r
+- list connection-definition{\r
+- key "id";\r
+- leaf id {\r
+- description "A unique ID for a kind of connection definition";\r
+- type nemo-common:connection-definition-id;\r
+- mandatory true;\r
+- } \r
+- leaf connection-type{\r
+- description "A user-readable description";\r
+- type nemo-common:connection-definition-type;\r
+- mandatory true; \r
+- }\r
+- uses property-definition; \r
+- } \r
+- }\r
+- \r
+- \r
+- grouping match-item-definition{\r
+- \r
+- list match-item {\r
+- description "";\r
+- key "name";\r
+- leaf name {\r
+- description "A user-visible name for the match-item";\r
++\r
++ leaf is-read-only {\r
++ description\r
++ "Specify whether the property is read-only for object.";\r
++ default write-read;\r
++ type enumeration {\r
++ enum write-read {\r
++ description\r
++ "The property can be read and written.";\r
++ }\r
++ enum read-only {\r
++ description\r
++ "The property is read-only.";\r
++ }\r
++ }\r
++ }\r
++ }\r
++ }\r
++\r
++ container node-definitions {\r
++ list node-definition {\r
++ description\r
++ "Define new node model/type which can be used in other places,\r
++ and include node type name and its property.";\r
++\r
++ key "node-type";\r
++ leaf node-type {\r
++ description\r
++ "A user-visible and unique identifier for the node type.";\r
++ type nemo-common:node-type;\r
++ mandatory true;\r
++ }\r
++\r
++ uses property-definitions;\r
++ }\r
++ }\r
++\r
++ container connection-definitions {\r
++ list connection-definition {\r
++ description\r
++ "Define new connection model/type which can be used in other places,\r
++ and include connection type name and its property.";\r
++\r
++ key "connection-type";\r
++ leaf connection-type {\r
++ description\r
++ "A user-visible and unique identifier for the connection type.";\r
++ type nemo-common:connection-type;\r
++ mandatory true;\r
++ }\r
++\r
++ uses property-definitions;\r
++ }\r
++ }\r
++\r
++ container match-item-definitions {\r
++ list match-item-definition {\r
++ description\r
++ "Define the match item which uses to match the flow.";\r
++\r
++ key "match-item-name";\r
++ leaf match-item-name {\r
++ description\r
++ "A user-visible and unique name for the match item.";\r
+ type nemo-common:match-item-name;\r
+ mandatory true;\r
+ }\r
+- leaf value-type {\r
+- description "The type of the match item";\r
++\r
++ leaf match-item-value-type {\r
++ description\r
++ "The value type of the match item.";\r
+ default string;\r
+ type enumeration {\r
+ enum string {\r
+- description "A string-valued match item";\r
++ description\r
++ "A string-valued match item.";\r
+ }\r
+ enum int {\r
+- description "An integer-valued match item";\r
++ description\r
++ "An integer-valued match item.";\r
+ }\r
+ enum range {\r
+- description "An integer-range match item";\r
++ description\r
++ "An integer-range match item.";\r
+ }\r
+ }\r
+ }\r
+- leaf is-required {\r
+- description "Specify whether the match item is required \r
+- for the flow.";\r
+- default optional;\r
+- type enumeration {\r
+- enum required {\r
+- description "The match item is required";\r
+- }\r
+- enum optional {\r
+- description "The match item is optional";\r
+- }\r
++ }\r
++ }\r
++\r
++ container flow-property-definitions {\r
++ description\r
++ "Contains the property definitions for the flow.";\r
++\r
++ uses property-definitions;\r
++ }\r
++\r
++ grouping property-instance {\r
++ description\r
++ "The property instance and its associated metadata.";\r
++\r
++ leaf property-name {\r
++ description\r
++ "The name for the property which can be seen as a unique\r
++ identifier of the property.";\r
++ type nemo-common:property-name;\r
++ mandatory true;\r
++ }\r
++\r
++ container property-values {\r
++ description\r
++ "The value list of the property.";\r
++\r
++ list string-value {\r
++ key "value order";\r
++ leaf value {\r
++ type string;\r
++ }\r
++\r
++ leaf order {\r
++ type uint32;\r
+ }\r
+ }\r
+- } \r
+- } \r
+- container flow-definitions{\r
+- list flow-definition{\r
+- key "id";\r
+- leaf id {\r
+- description "A unique ID for a kind of flow definition";\r
+- type nemo-common:flow-definition-id;\r
+- mandatory true;\r
+- } \r
+- leaf flow-type{\r
+- description "A user-readable description";\r
+- type nemo-common:flow-definition-type;\r
+- mandatory true; \r
+- }\r
+- uses match-item-definition; \r
+- } \r
+- }\r
+- \r
+- grouping node-property-instance{\r
+- list property {\r
+- key "name";\r
+- leaf name {\r
+- type nemo-common:node-property-name;\r
+- mandatory true;\r
+- }\r
+- leaf string-value {\r
+- type string;\r
+- }\r
+- leaf int-value {\r
+- type int64;\r
+- }\r
+- container range-value {\r
+- leaf min {\r
++\r
++ list int-value {\r
++ key "value order";\r
++ leaf value {\r
+ type int64;\r
+- mandatory true;\r
+ }\r
+- leaf max {\r
+- type int64;\r
+- mandatory true;\r
++\r
++ leaf order {\r
++ type uint32;\r
+ }\r
+ }\r
+- } \r
+- } \r
+- grouping node-instance{\r
+- description "";\r
+- leaf node-id {\r
+- description "A unique ID for the node instance";\r
+- type nemo-common:node-instance-id;\r
+- mandatory true;\r
+- }\r
+- leaf node-name {\r
+- description\r
+- "A user-visible name for the node definition";\r
+- type nemo-common:node-instance-name;\r
+- }\r
+- leaf node-type {\r
+- type nemo-common:node-instance-type;\r
+- mandatory true; \r
+- }\r
+- container subnodes{ \r
+- leaf-list subnode-id{\r
+- type nemo-common:node-instance-id; \r
+- } \r
+- }\r
+- container property{\r
+- uses node-property-instance; \r
+- } \r
+- }\r
+- \r
+- grouping connection-property-instance{\r
+- list property {\r
+- key "name";\r
+- leaf name {\r
+- type nemo-common:connection-property-name;\r
+- mandatory true;\r
+- }\r
+- leaf string-value {\r
+- type string;\r
+- }\r
+- leaf int-value {\r
+- type int64;\r
+- }\r
++\r
+ container range-value {\r
+ leaf min {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
++\r
+ leaf max {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+ }\r
+- } \r
+- } \r
+- grouping connection-instance {\r
+- description "";\r
+- leaf connection-id {\r
+- description "A unique ID for the connection instance";\r
+- type nemo-common:connection-instance-id;\r
+- mandatory true;\r
+- }\r
+- leaf connection-name {\r
+- description "A user-visible name for the connection instance";\r
+- type nemo-common:connection-instance-name;\r
+- mandatory false;\r
+- }\r
+- leaf connection-type {\r
+- type nemo-common:connection-instance-type;\r
+- mandatory true; \r
+- }\r
+- container endnodes{\r
+- list one-end{\r
+- key "node-id";\r
+- leaf node-id{\r
+- type nemo-common:node-instance-id; \r
+- }\r
+- min-elements 1;\r
+- } \r
+- list the-other-end{\r
+- key "node-id";\r
+- leaf node-id{\r
+- type nemo-common:node-instance-id;\r
+- }\r
+- min-elements 1; \r
+- } \r
+- }\r
+- container property{\r
+- uses connection-property-instance; \r
+- } \r
+- }\r
+- \r
+- grouping match-item-instance{\r
+- list match-item {\r
+- key "name";\r
+- leaf name {\r
+- type string;\r
+- mandatory true;\r
++ }\r
++ }\r
++\r
++ grouping node-instance {\r
++ description\r
++ "It represents the node instance and its metadata.\r
++ A node represents the functions a network node may provide in a\r
++ network such as network services,or a group of network elements.";\r
++\r
++ leaf node-id {\r
++ description\r
++ "A unique ID for a node instance";\r
++ type nemo-common:node-id;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf node-name {\r
++ description\r
++ "A user-visible and unique name for a node instance.";\r
++ type nemo-common:node-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf node-type {\r
++ description\r
++ "A user-visible and unique type identifier for a node instance.";\r
++ type nemo-common:node-type;\r
++ mandatory true;\r
++ }\r
++\r
++ list sub-node {\r
++ description\r
++ "Represents the sub-nodes which have been included\r
++ by the node instance logically.";\r
++\r
++ key "node-id";\r
++ leaf node-id {\r
++ description\r
++ "A unique ID for a node instance.";\r
++ type nemo-common:node-id;\r
++ }\r
++\r
++ leaf order {\r
++ description\r
++ "Specify the order of the node in a sequence node list.";\r
++ type uint32;\r
++ }\r
++ }\r
++\r
++ list property {\r
++ description\r
++ "The property list of a node instance.";\r
++\r
++ key "property-name";\r
++ uses property-instance;\r
++ }\r
++ }\r
++\r
++ grouping connection-instance {\r
++ description\r
++ "It represents the connection instance and its metadata.\r
++ The Connection describes the resource between node entities.\r
++ This connection is not limited to any physical link, but just\r
++ expresses the communication capacity between nodes.";\r
++\r
++ leaf connection-id {\r
++ description\r
++ "A unique ID for a connection instance.";\r
++ type nemo-common:connection-id;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf connection-name {\r
++ description\r
++ "A user-visible and unique name for a connection instance.";\r
++ type nemo-common:connection-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf connection-type {\r
++ description\r
++ "A user-visible and unique type identifier for a connection instance.";\r
++ type nemo-common:connection-type;\r
++ mandatory true;\r
++ }\r
++\r
++ list end-node {\r
++ description\r
++ "Represents the nodes which will be connected by connection.\r
++ At least two nodes in the list.";\r
++\r
++ key "node-id";\r
++ leaf node-id {\r
++ description\r
++ "A unique ID for a node instance.";\r
++ type nemo-common:node-id;\r
++ }\r
++\r
++ leaf order {\r
++ description\r
++ "Specify the order of the node in a sequence node list";\r
++ type uint32;\r
+ }\r
++\r
++ min-elements 2;\r
++ }\r
++\r
++ list property {\r
++ description\r
++ "The property list of a connection instance.";\r
++\r
++ key "property-name";\r
++ uses property-instance;\r
++ }\r
++ }\r
++\r
++ grouping match-item-instance {\r
++ description\r
++ "Represents the match item and its metadata.";\r
++\r
++ leaf match-item-name {\r
++ description\r
++ "A name for a match item.";\r
++ type nemo-common:match-item-name;\r
++ mandatory true;\r
++ }\r
++\r
++ container match-item-value {\r
++ description\r
++ "The value of a match item.";\r
++\r
+ leaf string-value {\r
+ type string;\r
+ }\r
++\r
+ leaf int-value {\r
+ type int64;\r
+ }\r
++\r
+ container range-value {\r
+ leaf min {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
++\r
+ leaf max {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+ }\r
+- } \r
+- }\r
+- grouping has-direction {\r
+- description "Object that have a directionality."; \r
+- leaf direction {\r
+- default bidirectional;\r
+- type enumeration {\r
+- enum in {\r
+- description\r
+- "Applies to flow into provider node";\r
+- }\r
+- enum out {\r
+- description\r
+- "Applies to flow out of provider node";\r
+- }\r
+- enum bidirectional {\r
+- description\r
+- "Applies to flow in both directions";\r
+- }\r
+- }\r
+ }\r
+- } \r
+- grouping flow-instance{\r
+- leaf flow-id {\r
+- description "A unique ID for the flow instance";\r
+- type nemo-common:flow-instance-id;\r
+- mandatory true;\r
+- }\r
+- leaf flow-name {\r
+- description "A user-visible name for the flow instance";\r
+- type nemo-common:flow-instance-name;\r
+- mandatory false;\r
+- }\r
+- leaf flow-type {\r
+- type nemo-common:flow-instance-type;\r
+- mandatory true; \r
+- }\r
+- container match {\r
+- uses has-direction;\r
+- uses match-item-instance;\r
+- }\r
+- } \r
+- \r
++ }\r
++\r
++ grouping flow-instance {\r
++ description\r
++ "Represents the flow instance and its metadata.\r
++ The flow refers to the traffic in network which describes\r
++ data packets have some certain characters.";\r
++\r
++ leaf flow-id {\r
++ description\r
++ "A unique ID for a flow instance.";\r
++ type nemo-common:flow-id;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf flow-name {\r
++ description\r
++ "A user-visible and unique name for a flow instance.";\r
++ type nemo-common:flow-name;\r
++ mandatory true;\r
++ }\r
++\r
++ list match-item {\r
++ description\r
++ "The match item list of a flow instance.";\r
++\r
++ key "match-item-name";\r
++ uses match-item-instance;\r
++ }\r
++\r
++ list property {\r
++ description\r
++ "The property list of a flow instance.";\r
++\r
++ key "property-name";\r
++ uses property-instance;\r
++ }\r
++ }\r
+ }\r
+diff --git a/nemo-api/src/main/yang/nemo-operation.yang b/nemo-api/src/main/yang/nemo-operation.yang
+index 219b192..8b4083a 100644
+--- a/nemo-api/src/main/yang/nemo-operation.yang
++++ b/nemo-api/src/main/yang/nemo-operation.yang
+@@ -1,5 +1,5 @@
+ /*\r
+- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
++ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+@@ -7,201 +7,288 @@
+ */\r
+ \r
+ module nemo-operation {\r
++ yang-version 1;\r
+ \r
+- yang-version 1; \r
+- namespace "urn:opendaylight:params:xml:ns:yang:nemo:operation"; \r
+- prefix "nemo-operation";\r
+- \r
+- import nemo-common {prefix nemo-common;}\r
+- \r
+- revision "2015-06-29" {\r
++ namespace "urn:opendaylight:params:xml:ns:yang:nemo:operation";\r
++ prefix "nemo-operation";\r
++\r
++ import nemo-common {prefix nemo-common;}\r
++\r
++ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+- \r
+- grouping parameter-definition {\r
+- leaf name {\r
+- description "A user-visible name for parameter";\r
+- type nemo-common:parameter-name;\r
+- mandatory true;\r
+- } \r
+- leaf type {\r
+- description "The type of the parameter";\r
+- default string;\r
+- type enumeration {\r
+- enum string {\r
+- description "A string-valued parameter";\r
+- }\r
+- enum int {\r
+- description "An integer-valued parameter";\r
+- }\r
+- enum range {\r
+- description "An integer-range parameter";\r
+- }\r
+- }\r
+- } \r
+- leaf is-required {\r
+- description "Specify whether the parameter is required ";\r
+- default optional;\r
+- type enumeration {\r
+- enum required {\r
+- description "The parameter is required";\r
+- }\r
+- enum optional {\r
+- description "The parameter is optional";\r
+- }\r
+- }\r
+- } \r
+- }\r
+- \r
+- \r
+- container action-definitions {\r
+- list action-definition { \r
+- key "action-name";\r
+- leaf action-name {\r
+- description "A name for the action definition";\r
+- type nemo-common:action-definition-name;\r
+- mandatory true; \r
+- } \r
+- list data {\r
+- description\r
+- "data for the action that can be passed in.";\r
+- key "name"; \r
+- uses parameter-definition; \r
+- } \r
+- }\r
+- } \r
+- grouping action-parameter-instance{\r
+- leaf data-name {\r
+- type nemo-common:data-name;\r
+- mandatory true;\r
+- }\r
+- leaf string-value {\r
+- type string;\r
+- }\r
+- leaf int-value {\r
+- type int64;\r
+- }\r
+- container range-value {\r
+- leaf min {\r
+- type int64;\r
+- mandatory true;\r
+- }\r
+- leaf max {\r
+- type int64;\r
+- mandatory true;\r
+- }\r
+- } \r
+- } \r
+- grouping action-instance{\r
+- description " ";\r
+- leaf action-name{\r
+- type nemo-common:action-instance-name;\r
+- mandatory true;\r
+- }\r
+- list data {\r
+- key "data-name";\r
+- uses action-parameter-instance; \r
+- } \r
+- }\r
+- \r
+- container condition-definitions {\r
+- list condition-definition{\r
+- key "condition-name";\r
+- leaf condition-name{\r
+- type nemo-common:condition-definition-name;\r
+- mandatory true; \r
+- }\r
+- list condition-parameter{\r
+- key "name";\r
+- uses parameter-definition;\r
+- min-elements 1;\r
+- } \r
+- }\r
+- }\r
+- grouping conditon-parameter-instance{\r
+- leaf parameter-name {\r
+- type nemo-common:condition-parameter-name;\r
+- mandatory true;\r
+- }\r
+- leaf string-value {\r
+- type string;\r
+- }\r
+- leaf int-value {\r
+- type int64;\r
+- }\r
+- container range-value {\r
+- leaf min {\r
+- type int64;\r
+- mandatory true;\r
+- }\r
+- leaf max {\r
+- type int64;\r
+- mandatory true;\r
+- }\r
+- } \r
+- } \r
+- grouping condition-instance {\r
+- description " ";\r
+- leaf condition-name{\r
+- type nemo-common:condition-instance-name;\r
+- mandatory true; \r
+- } \r
+- list condition-parameter{\r
+- key "parameter-name";\r
+- uses conditon-parameter-instance;\r
+- min-elements 1;\r
+- }\r
+- }\r
+- \r
+- \r
+- container constraint-definitions {\r
+- list constraint-definition{\r
+- key "constraint-name";\r
+- leaf constraint-name{\r
+- type nemo-common:constraint-definition-name;\r
+- mandatory true; \r
+- }\r
+- list constraint-parameter{\r
+- key "name";\r
+- uses parameter-definition;\r
+- min-elements 1;\r
+- } \r
+- }\r
+- }\r
+- grouping constraint-parameter-instance{\r
+- leaf parameter-name {\r
+- type nemo-common:constraint-parameter-name;\r
+- mandatory true;\r
+- }\r
+- leaf string-value {\r
+- type string;\r
+- }\r
+- leaf int-value {\r
+- type int64;\r
+- }\r
+- container range-value {\r
+- leaf min {\r
+- type int64;\r
+- mandatory true;\r
+- }\r
+- leaf max {\r
+- type int64;\r
+- mandatory true;\r
+- }\r
+- } \r
+- } \r
+- grouping constraint-instance {\r
+- description " ";\r
+- leaf constraint-name{\r
+- type nemo-common:constraint-instance-name;\r
+- mandatory true; \r
+- } \r
+- list constraint-parameter{\r
+- key "parameter-name";\r
+- uses constraint-parameter-instance;\r
+- min-elements 1;\r
+- }\r
+- }\r
+- \r
+-}
+\ No newline at end of file
++\r
++ container condition-parameter-definitions {\r
++ list condition-parameter-definition {\r
++ description\r
++ "Defines the condition parameter with its metadata.";\r
++\r
++ key "parameter-name";\r
++ leaf parameter-name {\r
++ description\r
++ "A name for the condition parameter.";\r
++ type nemo-common:parameter-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf parameter-value-type {\r
++ description\r
++ "A type of value for the condition parameter.";\r
++ type enumeration {\r
++ enum string {\r
++ description\r
++ "A string-valued parameter.";\r
++ }\r
++ enum int {\r
++ description\r
++ "An integer-valued parameter.";\r
++ }\r
++ enum range {\r
++ description\r
++ "An integer-range parameter.";\r
++ }\r
++ }\r
++ }\r
++\r
++ container parameter-match-patterns {\r
++ description\r
++ "Defines the match patterns of the condition parameter.";\r
++\r
++ leaf-list parameter-match-pattern {\r
++ type enumeration {\r
++ enum less-than;\r
++ enum not-less-than;\r
++ enum equal;\r
++ enum not-equal;\r
++ enum greater-than;\r
++ enum not-greater-than;\r
++ enum between;\r
++ enum periodical;\r
++ }\r
++ }\r
++ }\r
++ }\r
++ }\r
++\r
++ container action-definitions {\r
++ list action-definition {\r
++ description\r
++ "Defines the actions which will be supported by the NEMO project.";\r
++\r
++ key "action-name";\r
++ leaf action-name {\r
++ description\r
++ "A name for the action definition.";\r
++ type nemo-common:action-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf parameter-value-type {\r
++ description\r
++ "The type of the action parameter.";\r
++ default string;\r
++ type enumeration {\r
++ enum string {\r
++ description\r
++ "A string-valued parameter.";\r
++ }\r
++ enum int {\r
++ description\r
++ "An integer-valued parameter.";\r
++ }\r
++ enum range {\r
++ description\r
++ "An integer-range parameter.";\r
++ }\r
++ }\r
++ }\r
++ }\r
++ }\r
++\r
++ grouping condition-instance {\r
++ description\r
++ "Specific a instance of condition whose metadata has been filled in.";\r
++\r
++ list condition-segment {\r
++ description\r
++ "The segment entities will be composed into a whole condition entity.\r
++ Each segment will be a sub expression of the condition.";\r
++\r
++ key "condition-segment-id";\r
++ leaf condition-segment-id {\r
++ description\r
++ "A unique ID for a condition segment.";\r
++ type nemo-common:condition-segment-id;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf condition-parameter-name {\r
++ description\r
++ "A name for a conditon parameter.";\r
++ type nemo-common:condition-parameter-name;\r
++ }\r
++\r
++ leaf condition-parameter-match-pattern {\r
++ description\r
++ "The operator for the condition parameter and it's target value.";\r
++ type enumeration {\r
++ enum less-than;\r
++ enum not-less-than;\r
++ enum equal;\r
++ enum not-equal;\r
++ enum greater-than;\r
++ enum not-greater-than;\r
++ enum between;\r
++ enum periodical;\r
++ }\r
++ }\r
++\r
++ container condition-parameter-target-value {\r
++ description\r
++ "The target value of condition parameter.";\r
++\r
++ leaf string-value {\r
++ type string;\r
++ }\r
++\r
++ leaf int-value {\r
++ type int64;\r
++ }\r
++\r
++ container range-value {\r
++ leaf min {\r
++ type int64;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf max {\r
++ type int64;\r
++ mandatory true;\r
++ }\r
++ }\r
++ }\r
++\r
++ leaf precursor-relation-operator {\r
++ description\r
++ "The logical operator between current segment and the next segment.";\r
++ type enumeration {\r
++ enum none;\r
++ enum and;\r
++ enum or;\r
++ enum not;\r
++ }\r
++ }\r
++\r
++ leaf order {\r
++ description\r
++ "The order of the segment in the whole condition entity.";\r
++ type uint32;\r
++ }\r
++ }\r
++ }\r
++\r
++ grouping action-instance {\r
++ description\r
++ "Specific a action instance whose metadata has been filled in.";\r
++\r
++ leaf action-name {\r
++ description\r
++ "A name for a action instance.";\r
++ type nemo-common:action-name;\r
++ mandatory true;\r
++ }\r
++\r
++ container parameter-values {\r
++ description\r
++ "The parameter value list of an action.";\r
++\r
++ list string-value {\r
++ key "value order";\r
++ leaf value {\r
++ type string;\r
++ }\r
++\r
++ leaf order {\r
++ type uint32;\r
++ }\r
++ }\r
++\r
++ list int-value {\r
++ key "value order";\r
++ leaf value {\r
++ type int64;\r
++ }\r
++\r
++ leaf order {\r
++ type uint32;\r
++ }\r
++ }\r
++\r
++ container range-value {\r
++ leaf min {\r
++ type int64;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf max {\r
++ type int64;\r
++ mandatory true;\r
++ }\r
++ }\r
++ }\r
++ }\r
++\r
++ grouping operation-instance {\r
++ description\r
++ "Specific an operation instance whose metadata has been filled in.\r
++ Operation is a type of intent which refers to taking for some specific\r
++ actions to realize the purpose.";\r
++\r
++ leaf operation-id {\r
++ description\r
++ "A unique ID for a operation instance.";\r
++ type nemo-common:operation-id;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf operation-name {\r
++ description\r
++ "A user-visible and unique name for a operation instance.";\r
++ type nemo-common:operation-name;\r
++ mandatory true;\r
++ }\r
++\r
++ leaf priority {\r
++ description\r
++ "Defines the priority of a operation instance.";\r
++ type uint32;\r
++ default 0;\r
++ }\r
++\r
++ leaf target-object {\r
++ description\r
++ "The target object which the operation instance will apply to.";\r
++ type nemo-common:object-id;\r
++ mandatory true;\r
++ }\r
++\r
++ uses condition-instance;\r
++\r
++ list action {\r
++ description\r
++ "The action list for the operation instance.";\r
++\r
++ key "action-name";\r
++ uses action-instance;\r
++\r
++ leaf order {\r
++ description\r
++ "The order of an action instance in execution sequence.";\r
++ type uint32;\r
++ }\r
++\r
++ min-elements 1;\r
++ }\r
++ }\r
++}\r
+diff --git a/nemo-api/src/main/yang/nemo-result.yang b/nemo-api/src/main/yang/nemo-result.yang
+index b350c21..6daf69b 100644
+--- a/nemo-api/src/main/yang/nemo-result.yang
++++ b/nemo-api/src/main/yang/nemo-result.yang
+@@ -1,58 +1,23 @@
+ /*\r
+- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
++ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+ \r
+-module nemo-result{\r
++module nemo-result {\r
++ yang-version 1;\r
+ \r
+- yang-version 1; \r
+- namespace "urn:opendaylight:params:xml:ns:yang:nemo:result"; \r
+- prefix "nemo-result";\r
+- \r
+- import nemo-common {prefix nemo-common;}\r
+- \r
+- revision "2015-06-29" {\r
++ namespace "urn:opendaylight:params:xml:ns:yang:nemo:result";\r
++ prefix "nemo-result";\r
++\r
++ import nemo-common {prefix nemo-common;}\r
++\r
++ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+- \r
+- container expected-definitons{\r
+- \r
+- } \r
+- \r
+- grouping expected-instance {\r
+- leaf expected-id {\r
+- type nemo-common:expected-instance-id;\r
+- mandatory true;\r
+- }\r
+- leaf expected-name{\r
+- type nemo-common:expected-instance-name;\r
+- mandatory false;\r
+- }\r
+- leaf expected-description {\r
+- type nemo-common:description;\r
+- } \r
+- }\r
+- \r
+- container avoid-definitons{\r
+- \r
+- }\r
+ \r
+- grouping avoid-instance {\r
+- leaf avoid-id {\r
+- type nemo-common:avoid-instance-id;\r
+- mandatory true;\r
+- }\r
+- leaf avoid-name{\r
+- type nemo-common:avoid-instance-name;\r
+- mandatory false;\r
+- }\r
+- leaf avoid-description {\r
+- type nemo-common:description;\r
+- } \r
+- }\r
+- \r
+-}
+\ No newline at end of file
++ // TBD\r
++}\r
+diff --git a/nemo-features/pom.xml b/nemo-features/pom.xml
+index c678d52..e4db9ed 100644
+--- a/nemo-features/pom.xml
++++ b/nemo-features/pom.xml
+@@ -26,10 +26,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </prerequisites>
+
+ <properties>
+- <controller.mdsal.version>1.3.0-SNAPSHOT</controller.mdsal.version>
+ <mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
++ <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+ <restconf.version>1.3.0-SNAPSHOT</restconf.version>
+ <dlux.version>0.3.0-SNAPSHOT</dlux.version>
++ <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+ </properties>
+
+ <dependencyManagement>
+@@ -44,7 +45,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-artifacts</artifactId>
+- <version>${controller.mdsal.version}</version>
++ <version>${mdsal.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+@@ -97,6 +98,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
++
++ <dependency>
++ <groupId>org.opendaylight.openflowplugin</groupId>
++ <artifactId>features-openflowplugin</artifactId>
++ <version>${openflowplugin.version}</version>
++ <classifier>features</classifier>
++ <type>xml</type>
++ </dependency>
++ <dependency>
++ <groupId>org.opendaylight.openflowplugin</groupId>
++ <artifactId>features-openflowplugin-extension</artifactId>
++ <version>${openflowplugin.version}</version>
++ <classifier>features</classifier>
++ <type>xml</type>
++ </dependency>
++
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>nemo-api</artifactId>
+@@ -109,6 +126,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
++ <artifactId>nemo-impl</artifactId>
++ <version>${project.version}</version>
++ <classifier>config</classifier>
++ <type>xml</type>
++ </dependency>
++ <dependency>
++ <groupId>${project.groupId}</groupId>
+ <artifactId>openflow-renderer</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+@@ -121,6 +145,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
++ <artifactId>openflow-renderer</artifactId>
++ <version>${project.version}</version>
++ <classifier>resource</classifier>
++ <type>json</type>
++ </dependency>
++ <dependency>
++ <groupId>${project.groupId}</groupId>
+ <artifactId>nemo-ui</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+diff --git a/nemo-features/src/main/features/features.xml b/nemo-features/src/main/features/features.xml
+index 4cec890..f14ab7c 100644
+--- a/nemo-features/src/main/features/features.xml
++++ b/nemo-features/src/main/features/features.xml
+@@ -9,28 +9,37 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">\r
+ <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>\r
+- <repository>mvn:org.opendaylight.controller/features-mdsal/${controller.mdsal.version}/xml/features</repository>\r
++ <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>\r
+ <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>\r
+ <repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>\r
++ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>\r
++ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/${openflowplugin.version}/xml/features</repository>\r
+ <feature name='odl-nemo-api' version='${project.version}' description='OpenDaylight :: NEMO :: API'>\r
+ <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>\r
+ <bundle>mvn:org.opendaylight.nemo/nemo-api/${project.version}</bundle>\r
+ </feature>\r
+ <feature name='odl-nemo-engine' version='${project.version}' description='OpenDaylight :: NEMO :: Engine'>\r
+- <feature version='${controller.mdsal.version}'>odl-mdsal-broker</feature>\r
++ <feature version='${mdsal.version}'>odl-mdsal-broker</feature>\r
+ <feature version='${project.version}'>odl-nemo-api</feature>\r
+ <bundle>mvn:org.opendaylight.nemo/nemo-impl/${project.version}</bundle>\r
++ <configfile finalname='etc/opendaylight/karaf/00-nemo-engine.xml'>mvn:org.opendaylight.nemo/nemo-impl/${project.version}/xml/config</configfile>\r
+ </feature>\r
+ <feature name='odl-nemo-engine-rest' version='${project.version}' description='OpenDaylight :: NEMO :: Engine :: REST'>\r
+ <feature version='${restconf.version}'>odl-restconf</feature>\r
+- <feature version='${restconf.version}'>odl-mdsal-apidocs</feature>\r
+- <feature version='${controller.mdsal.version}'>odl-mdsal-xsql</feature>\r
++ <feature version='${mdsal.version}'>odl-mdsal-apidocs</feature>\r
++ <feature version='${mdsal.version}'>odl-mdsal-xsql</feature>\r
+ <feature version='${project.version}'>odl-nemo-engine</feature>\r
+ </feature>\r
+ <feature name='odl-nemo-openflow-renderer' version='${project.version}' description='OpenDaylight :: NEMO :: OpenFlow Renderer'>\r
+- <feature version='${project.version}'>odl-nemo-engine</feature>\r
++ <feature version='${openflowplugin.version}'>odl-openflowplugin-flow-services</feature>\r
++ <feature version='${openflowplugin.version}'>odl-openflowplugin-nxm-extensions</feature>\r
++ <feature version='${project.version}'>odl-nemo-engine-rest</feature>\r
+ <bundle>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}</bundle>\r
+- <configfile finalname='etc/opendaylight/karaf/00-nemo-openflow-renderer.xml'>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}/xml/config</configfile>\r
++ <configfile finalname='etc/opendaylight/karaf/01-nemo-openflow-renderer.xml'>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}/xml/config</configfile>\r
++ <configfile finalname='etc/nemo/nemo-openflow-renderer-resource.json'>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}/json/resource</configfile>\r
++ </feature>\r
++ <feature name='odl-nemo-cli-renderer' version='${project.version}' description='OpenDaylight :: NEMO :: CLI Renderer'>\r
++ <feature version='${project.version}'>odl-nemo-engine-rest</feature>\r
+ </feature>\r
+ <feature name='odl-nemo-engine-ui' version='${project.version}' description='OpenDaylight :: NEMO :: Engine :: UI'>\r
+ <feature version='${dlux.version}'>odl-dlux-core</feature>\r
+diff --git a/nemo-impl/pom.xml b/nemo-impl/pom.xml
+index fdb8145..c66209c 100644
+--- a/nemo-impl/pom.xml
++++ b/nemo-impl/pom.xml
+@@ -10,9 +10,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+- <groupId>org.opendaylight.mdsal</groupId>
+- <artifactId>binding-parent</artifactId>
+- <version>0.8.0-SNAPSHOT</version>
++ <groupId>org.opendaylight.controller</groupId>
++ <artifactId>config-parent</artifactId>
++ <version>0.4.0-SNAPSHOT</version>
+ <relativePath />
+ </parent>
+
+@@ -24,15 +24,49 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+
+ <properties>
+ <jacoco.version>0.7.2.201409121644</jacoco.version>
++ <sonar.jacoco.reportPath>target/code-coverage/jacoco.exec</sonar.jacoco.reportPath>
++ <sonar.jacoco.itReportPath>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
+ </properties>
+
+ <dependencies>
+ <dependency>
++ <groupId>org.opendaylight.mdsal.model</groupId>
++ <artifactId>ietf-inet-types</artifactId>
++ </dependency>
++ <dependency>
++ <groupId>org.opendaylight.mdsal.model</groupId>
++ <artifactId>ietf-yang-types</artifactId>
++ </dependency>
++ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>nemo-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
++ <groupId>net.sourceforge.collections</groupId>
++ <artifactId>collections-generic</artifactId>
++ <version>4.01</version>
++ </dependency>
++ <dependency>
++ <groupId>net.sf.jung</groupId>
++ <artifactId>jung-api</artifactId>
++ <version>2.0.1</version>
++ </dependency>
++ <dependency>
++ <groupId>net.sf.jung</groupId>
++ <artifactId>jung-graph-impl</artifactId>
++ <version>2.0.1</version>
++ </dependency>
++ <dependency>
++ <groupId>net.sf.jung</groupId>
++ <artifactId>jung-algorithms</artifactId>
++ <version>2.0.1</version>
++ </dependency>
++ <dependency>
++ <groupId>com.google.guava</groupId>
++ <artifactId>guava</artifactId>
++ </dependency>
++ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+@@ -59,26 +93,101 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </pluginManagement>
+ <plugins>
+ <plugin>
+- <groupId>org.jacoco</groupId>
+- <artifactId>jacoco-maven-plugin</artifactId>
++ <groupId>org.opendaylight.yangtools</groupId>
++ <artifactId>yang-maven-plugin</artifactId>
++ <executions>
++ <execution>
++ <goals>
++ <goal>generate-sources</goal>
++ </goals>
++ <configuration>
++ <yangFilesRootDir>src/main/yang</yangFilesRootDir>
++ <codeGenerators>
++ <generator>
++ <codeGeneratorClass>
++ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
++ </codeGeneratorClass>
++ <outputBaseDir>
++ ${salGeneratorPath}
++ </outputBaseDir>
++ </generator>
++ </codeGenerators>
++ <inspectDependencies>true</inspectDependencies>
++ </configuration>
++ </execution>
++ </executions>
++ <dependencies>
++ <dependency>
++ <groupId>org.opendaylight.mdsal</groupId>
++ <artifactId>maven-sal-api-gen-plugin</artifactId>
++ <version>${yangtools.version}</version>
++ <type>jar</type>
++ </dependency>
++ </dependencies>
++ </plugin>
++ <plugin>
++ <groupId>org.apache.felix</groupId>
++ <artifactId>maven-bundle-plugin</artifactId>
++ <extensions>true</extensions>
+ <configuration>
+- <includes>
+- <include>org.opendaylight.nemo.*</include>
+- </includes>
++ <instructions>
++ <Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
++ <Import-Package>*;resolution:=optional</Import-Package>
++ <Embed-Dependency>
++ collections-generic,jung-api,jung-graph-impl,jung-algorithms
++ </Embed-Dependency>
++ <Embed-Transitive>true</Embed-Transitive>
++ <Embed-Directory>lib</Embed-Directory>
++ <Embed-StripGroup>true</Embed-StripGroup>
++ <_failok>true</_failok>
++ <_nouses>true</_nouses>
++ </instructions>
++ <manifestLocation>${project.build.outputDirectory}/META-INF</manifestLocation>
+ </configuration>
++ </plugin>
++ <plugin>
++ <groupId>org.codehaus.mojo</groupId>
++ <artifactId>build-helper-maven-plugin</artifactId>
++ <executions>
++ <execution>
++ <id>attach-artifacts</id>
++ <goals>
++ <goal>attach-artifact</goal>
++ </goals>
++ <phase>package</phase>
++ <configuration>
++ <artifacts>
++ <artifact>
++ <file>${project.build.directory}/classes/etc/opendaylight/karaf/config.xml</file>
++ <type>xml</type>
++ <classifier>config</classifier>
++ </artifact>
++ </artifacts>
++ </configuration>
++ </execution>
++ </executions>
++ </plugin>
++ <plugin>
++ <groupId>org.jacoco</groupId>
++ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+- <id>pre-test</id>
++ <id>pre-unit-test</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
++ <configuration>
++ <destFile>${sonar.jacoco.reportPath}</destFile>
++ </configuration>
+ </execution>
+ <execution>
+- <id>post-test</id>
++ <id>post-unit-test</id>
+ <goals>
+ <goal>report</goal>
+ </goals>
+- <phase>test</phase>
++ <configuration>
++ <dataFile>${sonar.jacoco.reportPath}</dataFile>
++ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+diff --git a/nemo-impl/src/main/java/README b/nemo-impl/src/main/java/README
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/nemo-impl/src/test/java/README b/nemo-impl/src/test/java/README
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/nemo-karaf/pom.xml b/nemo-karaf/pom.xml
+index 7f23a37..c5520cc 100644
+--- a/nemo-karaf/pom.xml
++++ b/nemo-karaf/pom.xml
+@@ -26,12 +26,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </prerequisites>
+
+ <properties>
+- <feature.test.version>1.6.0-SNAPSHOT</feature.test.version>
+ <feature.mdsal.version>1.3.0-SNAPSHOT</feature.mdsal.version>
+ <feature.dlux.version>0.3.0-SNAPSHOT</feature.dlux.version>
+- <feature.flow.version>1.3.0-SNAPSHOT</feature.flow.version>
+- <feature.yangtools.version>0.8.0-SNAPSHOT</feature.yangtools.version>
+- <feature.adsal.version>0.10.0-SNAPSHOT</feature.adsal.version>
+ </properties>
+
+ <dependencyManagement>
+@@ -61,14 +57,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+- <groupId>org.opendaylight.controller</groupId>
+- <artifactId>features-adsal</artifactId>
+- <classifier>features</classifier>
+- <version>${feature.adsal.version}</version>
+- <type>xml</type>
+- <scope>runtime</scope>
+- </dependency>
+- <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>features-dlux</artifactId>
+ <version>${feature.dlux.version}</version>
+diff --git a/nemo-renderers/openflow-renderer/pom.xml b/nemo-renderers/openflow-renderer/pom.xml
+index a88e190..ab0b3f5 100644
+--- a/nemo-renderers/openflow-renderer/pom.xml
++++ b/nemo-renderers/openflow-renderer/pom.xml
+@@ -24,9 +24,33 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+
+ <properties>
+ <jacoco.version>0.7.2.201409121644</jacoco.version>
++ <sonar.jacoco.reportPath>target/code-coverage/jacoco.exec</sonar.jacoco.reportPath>
++ <sonar.jacoco.itReportPath>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
++ <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
++ <liblldp.version>0.10.0-SNAPSHOT</liblldp.version>
+ </properties>
+
+ <dependencies>
++ <!-- model dependencies -->
++ <dependency>
++ <groupId>org.opendaylight.mdsal.model</groupId>
++ <artifactId>yang-ext</artifactId>
++ </dependency>
++ <!-- project specific dependencies -->
++ <dependency>
++ <groupId>org.opendaylight.openflowplugin</groupId>
++ <artifactId>openflowplugin-extension-nicira</artifactId>
++ <version>${openflowplugin.version}</version>
++ </dependency>
++ <dependency>
++ <groupId>org.opendaylight.controller</groupId>
++ <artifactId>liblldp</artifactId>
++ <version>${liblldp.version}</version>
++ </dependency>
++ <dependency>
++ <groupId>commons-net</groupId>
++ <artifactId>commons-net</artifactId>
++ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>nemo-api</artifactId>
+@@ -38,6 +62,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
++ <groupId>org.mockito</groupId>
++ <artifactId>mockito-all</artifactId>
++ <scope>test</scope>
++ </dependency>
++ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+@@ -47,6 +76,18 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <scope>test</scope>
+ </dependency>
+ <dependency>
++ <groupId>com.fasterxml.jackson.core</groupId>
++ <artifactId>jackson-core</artifactId>
++ </dependency>
++ <dependency>
++ <groupId>com.fasterxml.jackson.core</groupId>
++ <artifactId>jackson-databind</artifactId>
++ </dependency>
++ <dependency>
++ <groupId>com.fasterxml.jackson.core</groupId>
++ <artifactId>jackson-annotations</artifactId>
++ </dependency>
++ <dependency>
+ <groupId>org.codehaus.jettison</groupId>
+ <artifactId>jettison</artifactId>
+ </dependency>
+@@ -64,6 +105,19 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </pluginManagement>
+ <plugins>
+ <plugin>
++ <groupId>org.apache.felix</groupId>
++ <artifactId>maven-bundle-plugin</artifactId>
++ <configuration>
++ <instructions>
++ <Export-Package>org.codehaus.jackson,
++ org.codehaus.jackson.*,
++ org.joda.time.*,
++ </Export-Package>
++ <Import-Package>*</Import-Package>
++ </instructions>
++ </configuration>
++ </plugin>
++ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <executions>
+@@ -108,6 +162,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
++ <artifact>
++ <file>${project.build.directory}/classes/etc/nemo/resource.json</file>
++ <type>json</type>
++ <classifier>resource</classifier>
++ </artifact>
+ <artifact>
+ <file>${project.build.directory}/classes/etc/opendaylight/karaf/config.xml</file>
+ <type>xml</type>
+@@ -128,17 +187,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ </configuration>
+ <executions>
+ <execution>
+- <id>pre-test</id>
++ <id>pre-unit-test</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
++ <configuration>
++ <destFile>${sonar.jacoco.reportPath}</destFile>
++ </configuration>
+ </execution>
+ <execution>
+- <id>post-test</id>
++ <id>post-unit-test</id>
+ <goals>
+ <goal>report</goal>
+ </goals>
+- <phase>test</phase>
++ <configuration>
++ <dataFile>${sonar.jacoco.reportPath}</dataFile>
++ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+diff --git a/nemo-renderers/openflow-renderer/src/main/java/README b/nemo-renderers/openflow-renderer/src/main/java/README
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/nemo-renderers/openflow-renderer/src/main/yang/openflow-renderer-impl.yang b/nemo-renderers/openflow-renderer/src/main/yang/openflow-renderer-impl.yang
+index dc8b4d9..0a1637e 100644
+--- a/nemo-renderers/openflow-renderer/src/main/yang/openflow-renderer-impl.yang
++++ b/nemo-renderers/openflow-renderer/src/main/yang/openflow-renderer-impl.yang
+@@ -19,7 +19,7 @@ module openflow-renderer-impl {
+ "This module contains the base YANG definitions for\r
+ NEMO Openflow renderer implementation.";\r
+ \r
+- revision "2015-07-01" {\r
++ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+diff --git a/nemo-renderers/openflow-renderer/src/test/java/README b/nemo-renderers/openflow-renderer/src/test/java/README
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/nemo-renderers/pom.xml b/nemo-renderers/pom.xml
+index 7066dda..1024502 100644
+--- a/nemo-renderers/pom.xml
++++ b/nemo-renderers/pom.xml
+@@ -5,7 +5,8 @@ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
++<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
++ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+@@ -27,7 +28,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</developerConnection>
+- <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/NEMO:Main</url>
++ <tag>HEAD</tag>
+ </scm>
+-</project>
++</project>
+\ No newline at end of file
+diff --git a/nemo-ui/src/main/resources/README b/nemo-ui/src/main/resources/README
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/pom.xml b/pom.xml
+index 22b85c9..d898151 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -5,14 +5,15 @@ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
++<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
++ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+- <groupId>org.opendaylight.controller</groupId>
+- <artifactId>releasepom</artifactId>
+- <version>0.3.0-SNAPSHOT</version>
+- <relativePath></relativePath>
++ <groupId>org.opendaylight.odlparent</groupId>
++ <artifactId>odlparent</artifactId>
++ <version>1.6.0-SNAPSHOT</version>
++ <relativePath />
+ </parent>
+
+ <groupId>org.opendaylight.nemo</groupId>
+@@ -30,10 +31,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <module>nemo-artifacts</module>
+ <module>nemo-api</module>
+ <module>nemo-impl</module>
++ <module>nemo-renderers</module>
+ <module>nemo-ui</module>
+ <module>nemo-features</module>
+ <module>nemo-karaf</module>
+- <module>nemo-renderers</module>
+ </modules>
+
+ <url>https://wiki.opendaylight.org/view/NEMO:Main</url>
+@@ -58,7 +59,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</developerConnection>
+- <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/NEMO:Main</url>
++ <tag>HEAD</tag>
+ </scm>
+ </project>
/*\r
- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
*\r
* This program and the accompanying materials are made available under the\r
* terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
* and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
\r
-module nemo-common{\r
- yang-version 1; \r
- namespace "urn:opendaylight:params:xml:ns:yang:nemo:common"; \r
- prefix "nemo-common";\r
- \r
- revision "2015-06-29" {\r
+module nemo-common {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:common";\r
+ prefix "nemo-common";\r
+\r
+ description\r
+ "Common types and definitions for NEMO models";\r
+\r
+ revision "2015-10-10" {\r
description\r
"Initial revision.";\r
}\r
- \r
- /**********************\r
- * Base types\r
- **********************/\r
- typedef description {\r
- description "A human-readable description for a object.";\r
+\r
+ // *********************\r
+ // * Base Types\r
+ // *********************\r
+ typedef description {\r
+ description\r
+ "A human-readable description for a object.";\r
type string {\r
length "1..4096";\r
}\r
}\r
- \r
- typedef name {\r
+\r
+ typedef name {\r
description\r
"A generic string name type. Must start with a letter";\r
type string {\r
length "1..256";\r
}\r
}\r
- \r
- // UUID type from ietf-yang-types@2013-07-15\r
+\r
+ // UUID type from ietf-yang-types@2013-07-15\r
typedef uuid {\r
type string {\r
pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'\r
}\r
description\r
"A Universally Unique IDentifier in the string representation\r
- defined in RFC 4122. The canonical representation uses\r
- lowercase characters.\r
+ defined in RFC 4122. The canonical representation uses\r
+ lower case characters.\r
\r
The following is an example of a UUID in string\r
representation: f81d4fae-7dec-11d0-a765-00a0c91e6bf6";\r
}\r
\r
typedef unique-id {\r
+ description\r
+ "A globally unique identifier.";\r
type uuid;\r
- description "A globally unique identifier";\r
}\r
- \r
- /*********************\r
- * Unique IDs\r
- *********************/ \r
- typedef object-id {\r
+\r
+ // *********************\r
+ // * Unique IDs\r
+ // *********************\r
+ typedef object-id {\r
+ description\r
+ "A unique ID for a parameterized object.";\r
type unique-id;\r
- description "A unique ID for a parameterized object";\r
}\r
- \r
- typedef node-definition-id {\r
- type object-id;\r
- description "A unique ID for a node definition.";\r
- }\r
- typedef node-instance-id {\r
- type object-id;\r
- description "A unique ID for a node instance.";\r
- } \r
- \r
- typedef connection-definition-id {\r
+\r
+ typedef node-id {\r
+ description\r
+ "A unique ID for a node.";\r
type object-id;\r
- description "A unique ID for a connection definition.";\r
}\r
- typedef connection-instance-id {\r
- type object-id;\r
- description "A unique ID for a connection instance.";\r
- } \r
- \r
- typedef flow-definition-id {\r
+\r
+ typedef connection-id {\r
+ description\r
+ "A unique ID for a connection.";\r
type object-id;\r
- description "A unique ID for a flow definition.";\r
}\r
- typedef flow-instance-id {\r
+\r
+ typedef flow-id {\r
+ description\r
+ "A unique ID for a flow.";\r
type object-id;\r
- description "A unique ID for a flow instance.";\r
}\r
- \r
- typedef expected-definition-id {\r
+\r
+ typedef intent-id {\r
+ description\r
+ "A unique ID for an intent.";\r
type unique-id;\r
- description "A unique ID for an expected definition.";\r
}\r
- typedef expected-instance-id {\r
+\r
+ typedef user-id {\r
+ description\r
+ "A unique ID for a user.";\r
type unique-id;\r
- description "A unique ID for an expected instance.";\r
}\r
- \r
- typedef avoid-definition-id {\r
+\r
+ typedef operation-id {\r
+ description\r
+ "A unique ID for an operation.";\r
type unique-id;\r
- description "A unique ID for an avoid definition.";\r
}\r
- typedef avoid-instance-id {\r
- type unique-id;\r
- description "A unique ID for an avoid instance.";\r
- }\r
- \r
- typedef context-id {\r
- type unique-id;\r
- description "A unique ID for a context.";\r
- }\r
- \r
- typedef intent-id {\r
+\r
+ typedef condition-segment-id {\r
+ description\r
+ "A unique ID for a segment of the condition in an operation.";\r
type unique-id;\r
- description "A unique ID for an intent.";\r
}\r
- \r
- typedef user-id {\r
+\r
+ typedef query-condition-id {\r
+ description\r
+ "A unique ID for a condition of the advanced query.";\r
type unique-id;\r
- description "A unique ID for a user.";\r
- }\r
- \r
- \r
- \r
- /*********************\r
- * names\r
- *********************/ \r
- typedef object-name {\r
+ }\r
+\r
+ // *********************\r
+ // * Names\r
+ // *********************\r
+ typedef object-name {\r
+ description\r
+ "A name for a parameterized object";\r
type name;\r
- description "A name for a parameterized object";\r
}\r
- \r
- typedef node-instance-name {\r
+\r
+ typedef node-name {\r
+ description\r
+ "A name for a node instance.";\r
type object-name;\r
- description "A name for a node instance.";\r
- } \r
- \r
- typedef connection-instance-name {\r
+ }\r
+\r
+ typedef connection-name {\r
+ description\r
+ "A name for a connection instance.";\r
type object-name;\r
- description "A name for a connection instance.";\r
- } \r
- \r
- typedef flow-instance-name {\r
+ }\r
+\r
+ typedef flow-name {\r
+ description\r
+ "A name for a flow instance.";\r
type object-name;\r
- description "A name for a flow instance.";\r
- } \r
- \r
- typedef node-property-name {\r
- type name;\r
- description "A name for a node property.";\r
- } \r
- \r
- typedef connection-property-name {\r
+ }\r
+\r
+ typedef match-item-name {\r
+ description\r
+ "A name for a match item.";\r
type name;\r
- description "A name for a connection property.";\r
- } \r
+ }\r
\r
- typedef match-item-name {\r
+ typedef property-name {\r
+ description\r
+ "A name for a property.";\r
type name;\r
- description "A name for a flow match item.";\r
}\r
- \r
- typedef property-name {\r
+\r
+ typedef parameter-name {\r
+ description\r
+ "A name for a parameter.";\r
type name;\r
- description "A name for a property.";\r
}\r
- \r
- typedef parameter-name {\r
+\r
+ typedef action-name {\r
+ description\r
+ "A name for an action.";\r
type name;\r
- description "A name for a parameter.";\r
}\r
- \r
- typedef action-definition-name {\r
+\r
+ typedef condition-parameter-name {\r
+ description\r
+ "A name for a parameter of condition.";\r
type name;\r
- description "A name for an action definition.";\r
- } \r
- typedef action-instance-name {\r
+ }\r
+\r
+ typedef user-name {\r
+ description\r
+ "A name for a user.";\r
type name;\r
- description "A name for an action instance.";\r
- } \r
- typedef condition-definition-name {\r
+ }\r
+\r
+ typedef user-password {\r
+ description\r
+ "A password for a user.";\r
type name;\r
- description "A name for a condition definition.";\r
- }\r
- typedef condition-instance-name {\r
- type name;\r
- description "A name for a condition instance.";\r
- }\r
- typedef condition-parameter-name {\r
- type name;\r
- description "A name for a condition parameter.";\r
- }\r
- typedef constraint-definition-name {\r
+ }\r
+\r
+ typedef operation-name {\r
+ description\r
+ "A name for an operation.";\r
type name;\r
- description "A name for a constraint definition.";\r
- }\r
- typedef constraint-instance-name {\r
- type name;\r
- description "A name for a constraint instance.";\r
- }\r
- typedef constraint-parameter-name {\r
- type name;\r
- description "A name for a constraint parameter.";\r
- }\r
- \r
-\r
- typedef data-name {\r
- type name;\r
- description "A name for an action data.";\r
- }\r
- \r
- typedef context-name {\r
- type name;\r
- description "A name for an context";\r
- }\r
- \r
- typedef intent-name {\r
+ }\r
+\r
+ typedef query-condition-name {\r
+ description\r
+ "A name for a query with condition.";\r
type name;\r
- description "A name for an intent.";\r
}\r
- typedef user-name {\r
+\r
+ typedef user-role-name {\r
+ description\r
+ "A role name for a user.";\r
type name;\r
- description "A name for a user.";\r
}\r
- typedef expected-instance-name {\r
+\r
+ typedef user-role-description {\r
+ description\r
+ "It describes the role characteristic and responsibility range.";\r
+ type string;\r
+ }\r
+\r
+ // *********************\r
+ // * Types\r
+ // *********************\r
+ typedef node-type {\r
+ description\r
+ "The type for a node.";\r
type name;\r
- description "A name for an expected instance.";\r
}\r
- typedef avoid-instance-name {\r
+\r
+ typedef connection-type {\r
+ description\r
+ "The type for a connection.";\r
type name;\r
- description "A name for an avoid instance.";\r
- }\r
- \r
- \r
- \r
- /*********************\r
- * types\r
- *********************/ \r
- typedef node-definition-type {\r
- type name;\r
- description "A type for a node."; \r
- }\r
- typedef connection-definition-type {\r
- type name;\r
- description "A type for a connection."; \r
- }\r
- typedef flow-definition-type {\r
- type name;\r
- description "A type for a flow."; \r
- } \r
- typedef node-instance-type {\r
- type name;\r
- description "A type for a node instance."; \r
- } \r
- typedef connection-instance-type {\r
- type name;\r
- description "A type for a connection instance."; \r
- }\r
- typedef flow-instance-type {\r
- type name;\r
- description "A type for a flow instance."; \r
- }\r
+ }\r
\r
+ typedef flow-type {\r
+ description\r
+ "The type for a flow.";\r
+ type name;\r
+ }\r
}\r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
-
\ No newline at end of file
/*\r
- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
*\r
* This program and the accompanying materials are made available under the\r
* terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
* and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
- \r
+\r
module nemo-intent {\r
- yang-version 1; \r
- namespace "urn:opendaylight:params:xml:ns:yang:nemo:intent"; \r
- prefix "nemo-intent";\r
- \r
- import nemo-common {prefix nemo-common;}\r
- import nemo-object {prefix nemo-object;}\r
- import nemo-operation {prefix nemo-operation;}\r
- import nemo-result {prefix nemo-result;}\r
- \r
- revision "2015-06-29" {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:intent";\r
+ prefix "nemo-intent";\r
+\r
+ import nemo-common {prefix nemo-common;}\r
+ import nemo-object {prefix nemo-object;}\r
+ import nemo-operation {prefix nemo-operation;}\r
+ import nemo-user {prefix nemo-user;}\r
+\r
+ revision "2015-10-10" {\r
description\r
"Initial revision.";\r
}\r
- \r
- grouping intent-instance {\r
- description "";\r
- leaf intent-id {\r
- description "A unique ID for the intent";\r
- type nemo-common:intent-id; \r
- mandatory true;\r
- } \r
- leaf intent-name {\r
- description "A user-visible name for the intent";\r
- type nemo-common:intent-name;\r
- } \r
- container objects {\r
- description "";\r
- list node {\r
- key "node-id";\r
- uses nemo-object:node-instance;\r
- } \r
- list connection {\r
- key "connection-id";\r
- uses nemo-object:connection-instance;\r
- } \r
- list flow {\r
- key "flow-id";\r
- uses nemo-object:flow-instance;\r
- } \r
- }\r
- \r
- container operation {\r
- leaf apply-on-object {\r
- type nemo-common:object-id;\r
- mandatory true;\r
- } \r
- leaf priority{\r
- type int64;\r
- default 1;\r
- }\r
- uses nemo-operation:condition-instance;\r
- uses nemo-operation:action-instance;\r
- uses nemo-operation:constraint-instance; \r
- }\r
- \r
- container result{\r
- leaf result-to-object {\r
- type nemo-common:object-id;\r
- mandatory true;\r
- } \r
- leaf priority{\r
- type int64;\r
- default 1;\r
- }\r
- choice result-mode {\r
- mandatory true;\r
- case expected-case {\r
- uses nemo-result:expected-instance;\r
- }\r
- case avoid-case{\r
- uses nemo-result:avoid-instance;\r
- } \r
- } \r
- } \r
- container contexts{\r
- list context {\r
- key "context-id";\r
- leaf context-id {\r
- type nemo-common:context-id;\r
- mandatory true;\r
- }\r
- leaf context-name{\r
- type nemo-common:context-name;\r
- mandatory true;\r
- }\r
- } \r
- }\r
- }\r
- \r
- container users {\r
- description "The list of all known users";\r
- list user {\r
- description "";\r
+\r
+ grouping user-intent {\r
+ description\r
+ "User intent refers to a purpose in getting an ultimate result\r
+ or performing some specific operation on some objects.";\r
+\r
+ container objects {\r
+ description\r
+ "The element could be operated and managed by users.\r
+ It inludes resources to construct users' virtual network,\r
+ and the services in this network.In NEMO project, it is\r
+ abstracted into node, connection and flow";\r
+\r
+ list node {\r
+ key "node-id";\r
+ uses nemo-object:node-instance;\r
+ }\r
+\r
+ list connection {\r
+ key "connection-id";\r
+ uses nemo-object:connection-instance;\r
+ }\r
+\r
+ list flow {\r
+ key "flow-id";\r
+ uses nemo-object:flow-instance;\r
+ }\r
+ }\r
+\r
+ container operations {\r
+ description\r
+ "The operation is to dynamically adjust the behavior of network,\r
+ and it is applied on objects, that is, node, connection and flow";\r
+\r
+ list operation {\r
+ key "operation-id";\r
+ uses nemo-operation:operation-instance;\r
+ }\r
+ }\r
+\r
+ container results {\r
+ // TBD\r
+ }\r
+ }\r
+\r
+ container users {\r
+ description\r
+ "The list of all known users";\r
+\r
+ list user {\r
+ description\r
+ "A user is an administrative domain which is\r
+ logically separated from other users, and each\r
+ intent is specified by a particular user.";\r
+\r
key "user-id";\r
- leaf user-id {\r
- description "A unique ID for the user"; \r
- type nemo-common:user-id;\r
- mandatory true;\r
- }\r
- leaf user-name {\r
- description "A user-visible name for the user";\r
- type nemo-common:user-name;\r
- mandatory false;\r
- } \r
- list intent{\r
- key "intent-id";\r
- uses intent-instance;\r
- min-elements 1;\r
- }\r
- } \r
- }\r
- \r
- rpc register-node-instance {\r
- description "";\r
- input {\r
- uses nemo-object:node-instance;\r
- }\r
- }\r
- \r
- rpc unregister-node-instance {\r
- description "";\r
- input {\r
- uses nemo-object:node-instance;\r
- }\r
- }\r
- \r
-}
\ No newline at end of file
+ uses nemo-user:user-instance;\r
+ uses user-intent;\r
+ }\r
+ }\r
+\r
+ container query-condition-definitions {\r
+ description\r
+ "Contains the definitions for all advanced query, which means\r
+ they are the query with conditions supported by the NEMO engine.\r
+ User will fetch all results which meet the condition.";\r
+\r
+ list query-condition-definition {\r
+ description\r
+ "Define the query with condition. For example, user may\r
+ intent to query all connection's name whose utilization is\r
+ beyond 80%. That is a query with condition.";\r
+\r
+ key "query-condition-name query-intent-type";\r
+ leaf query-condition-name {\r
+ description\r
+ "A user-visible name for the query condition definition.\r
+ The query condition name is usually to specify the\r
+ attribute or property of some kind of intent.\r
+ For the above example, the query-condition-name is utility.";\r
+ type nemo-common:query-condition-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf query-intent-type {\r
+ description\r
+ "The target for the query, and its attributes will be checked out\r
+ if meet the condition. In the above example, connection is the\r
+ target. So, connection will be the query-intent-type here.";\r
+ type enumeration {\r
+ enum node;\r
+ enum connection;\r
+ enum flow;\r
+ enum operation;\r
+ enum result;\r
+ }\r
+ }\r
+\r
+ leaf query-condition-value-type {\r
+ description\r
+ "The type of the target value for the query condition.\r
+ For the above example, the target-value is 80(%),\r
+ so the query-condition-value-type will be int.";\r
+ default string;\r
+ type enumeration {\r
+ enum string {\r
+ description\r
+ "A string-valued target value.";\r
+ }\r
+ enum int {\r
+ description\r
+ "An integer-valued target value.";\r
+ }\r
+ enum range {\r
+ description\r
+ "An integer-range target value.";\r
+ }\r
+ }\r
+ }\r
+\r
+ container query-condition-match-patterns {\r
+ description\r
+ "The relationship between the value of query-condition-name\r
+ and query-condition-target-value. If an intent's attribute\r
+ or property specified by the query condition name matches\r
+ to the target value by the match pattern, this intent meets\r
+ the condition. For the above example, the condition's\r
+ query-condition-match-patterns could be less-than, not-less-than,\r
+ equal, not-equal, greater-than, not-greater-than, between.";\r
+\r
+ leaf-list query-condition-match-pattern {\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping common-rpc-result {\r
+ description\r
+ "Common return result for all defined RPCs.";\r
+\r
+ leaf result-code {\r
+ description\r
+ "Result code which is convenient for processing in a program.";\r
+ type enumeration {\r
+ enum ok {\r
+ description\r
+ "The invoked RPC was executed successfully";\r
+ }\r
+ enum error {\r
+ description\r
+ "There's an error while executing the RPC";\r
+ }\r
+ }\r
+ }\r
+\r
+ leaf message {\r
+ description\r
+ "A human-readable message for an error or exception";\r
+ type string;\r
+ }\r
+ }\r
+\r
+ grouping query-condition-instance {\r
+ description\r
+ "A query condition instance generated according to\r
+ a specified query condition definition.";\r
+\r
+ leaf query-condition-id {\r
+ description\r
+ "A unique ID for a query condition instance.";\r
+ type nemo-common:query-condition-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf query-condition-name {\r
+ description\r
+ "The name of the query condition definition.";\r
+ type nemo-common:query-condition-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf query-intent-type {\r
+ description\r
+ "The type of the intents that the user wants to query from through\r
+ the condition instance.";\r
+ type enumeration {\r
+ enum node;\r
+ enum connection;\r
+ enum flow;\r
+ enum operation;\r
+ enum result;\r
+ }\r
+ }\r
+\r
+ leaf query-condition-match-pattern {\r
+ description\r
+ "The match pattern the condition instance will use.";\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ }\r
+ }\r
+\r
+ container query-condition-target-value {\r
+ description\r
+ "The target value used to compare with the attribute\r
+ or property of the intents.";\r
+\r
+ leaf string-value {\r
+ type string;\r
+ }\r
+\r
+ leaf int-value {\r
+ type int64;\r
+ }\r
+\r
+ container range-value {\r
+ leaf min {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf max {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ rpc register-user {\r
+ description\r
+ "Register a user to the user repository.";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ }\r
+ }\r
+\r
+ rpc begin-transaction {\r
+ description\r
+ "Begin a transaction for the user";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ }\r
+ }\r
+\r
+ rpc end-transaction {\r
+ description\r
+ "Commit the user's current transaction";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ }\r
+ }\r
+\r
+ rpc language-style-nemo-request {\r
+ description\r
+ "Create, update or delete an intent of a user through an NEMO statement";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+\r
+ leaf nemo-statement {\r
+ type string;\r
+ }\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ }\r
+ }\r
+\r
+ rpc structure-style-nemo-update {\r
+ description\r
+ "Create or update all or a part of the user's intents,\r
+ which are described as json or xml format.";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+ uses user-intent;\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ }\r
+ }\r
+\r
+ rpc structure-style-nemo-delete {\r
+ description\r
+ "Delete some intents of a user from the user repository";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+\r
+ container objects {\r
+ leaf-list node {\r
+ type nemo-common:node-id;\r
+ }\r
+\r
+ leaf-list connection {\r
+ type nemo-common:connection-id;\r
+ }\r
+\r
+ leaf-list flow {\r
+ type nemo-common:flow-id;\r
+ }\r
+ }\r
+\r
+ container operations {\r
+ leaf-list operation {\r
+ type nemo-common:operation-id;\r
+ }\r
+ }\r
+\r
+ container results {\r
+ // TBD\r
+ }\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ }\r
+ }\r
+\r
+ rpc advanced-nemo-query {\r
+ description\r
+ "Query some intents of a user from the user repository\r
+ according to several advanced query conditions.";\r
+\r
+ input {\r
+ uses nemo-user:user-instance;\r
+\r
+ list query-condition {\r
+ key "query-condition-id";\r
+ uses query-condition-instance;\r
+ }\r
+ }\r
+\r
+ output {\r
+ uses common-rpc-result;\r
+ uses user-intent;\r
+ }\r
+ }\r
+}\r
/*\r
- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
*\r
* This program and the accompanying materials are made available under the\r
* terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
* and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
\r
-module nemo-object{\r
- yang-version 1; \r
- namespace "urn:opendaylight:params:xml:ns:yang:nemo:object"; \r
- prefix "nemo-object";\r
- \r
- import nemo-common {prefix nemo-common;}\r
- \r
- revision "2015-06-29" {\r
+module nemo-object {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:object";\r
+ prefix "nemo-object";\r
+\r
+ import nemo-common {prefix nemo-common;}\r
+\r
+ revision "2015-10-10" {\r
description\r
"Initial revision.";\r
}\r
- \r
- grouping property-definition { \r
- list property {\r
- description "";\r
- key "name";\r
- leaf name {\r
- description "A user-visible name for the property";\r
+\r
+ grouping property-definitions {\r
+ list property-definition {\r
+ description\r
+ "The property definitions for the type of node or connection.";\r
+\r
+ key "property-name";\r
+ leaf property-name {\r
+ description\r
+ "A user-visible and unique name for the property.";\r
type nemo-common:property-name;\r
mandatory true;\r
}\r
- leaf value-type {\r
- description "The type of the property";\r
+\r
+ leaf property-value-type {\r
+ description\r
+ "The type of the property value.";\r
default string;\r
type enumeration {\r
enum string {\r
- description "A string-valued property";\r
+ description\r
+ "An string-valued property.";\r
}\r
enum int {\r
- description "An integer-valued property";\r
+ description\r
+ "An integer-valued property.";\r
}\r
enum range {\r
- description "An integer-range property";\r
+ description\r
+ "An integer-range property.";\r
}\r
}\r
}\r
+\r
leaf is-required {\r
- description "Specify whether the property is\r
- required for object.";\r
+ description\r
+ "Specify whether the property is required for the object.";\r
default optional;\r
type enumeration {\r
enum required {\r
- description "The property is required";\r
+ description\r
+ "The property is required";\r
}\r
enum optional {\r
- description "The property is optional";\r
+ description\r
+ "The property is optional";\r
}\r
}\r
}\r
- } \r
- } \r
- container node-definitions{\r
- list node-definition{\r
- description "";\r
- key "id";\r
- leaf id {\r
- description "A unique ID for a kind of node definition";\r
- type nemo-common:node-definition-id;\r
- mandatory true;\r
- } \r
- leaf node-type{\r
- description "A user-readable description";\r
- type nemo-common:node-definition-type;\r
- mandatory true; \r
- }\r
- uses property-definition; \r
- } \r
- } \r
- container connection-definitions{\r
- list connection-definition{\r
- key "id";\r
- leaf id {\r
- description "A unique ID for a kind of connection definition";\r
- type nemo-common:connection-definition-id;\r
- mandatory true;\r
- } \r
- leaf connection-type{\r
- description "A user-readable description";\r
- type nemo-common:connection-definition-type;\r
- mandatory true; \r
- }\r
- uses property-definition; \r
- } \r
- }\r
- \r
- \r
- grouping match-item-definition{\r
- \r
- list match-item {\r
- description "";\r
- key "name";\r
- leaf name {\r
- description "A user-visible name for the match-item";\r
+\r
+ leaf is-read-only {\r
+ description\r
+ "Specify whether the property is read-only for object.";\r
+ default write-read;\r
+ type enumeration {\r
+ enum write-read {\r
+ description\r
+ "The property can be read and written.";\r
+ }\r
+ enum read-only {\r
+ description\r
+ "The property is read-only.";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ container node-definitions {\r
+ list node-definition {\r
+ description\r
+ "Define new node model/type which can be used in other places,\r
+ and include node type name and its property.";\r
+\r
+ key "node-type";\r
+ leaf node-type {\r
+ description\r
+ "A user-visible and unique identifier for the node type.";\r
+ type nemo-common:node-type;\r
+ mandatory true;\r
+ }\r
+\r
+ uses property-definitions;\r
+ }\r
+ }\r
+\r
+ container connection-definitions {\r
+ list connection-definition {\r
+ description\r
+ "Define new connection model/type which can be used in other places,\r
+ and include connection type name and its property.";\r
+\r
+ key "connection-type";\r
+ leaf connection-type {\r
+ description\r
+ "A user-visible and unique identifier for the connection type.";\r
+ type nemo-common:connection-type;\r
+ mandatory true;\r
+ }\r
+\r
+ uses property-definitions;\r
+ }\r
+ }\r
+\r
+ container match-item-definitions {\r
+ list match-item-definition {\r
+ description\r
+ "Define the match item which uses to match the flow.";\r
+\r
+ key "match-item-name";\r
+ leaf match-item-name {\r
+ description\r
+ "A user-visible and unique name for the match item.";\r
type nemo-common:match-item-name;\r
mandatory true;\r
}\r
- leaf value-type {\r
- description "The type of the match item";\r
+\r
+ leaf match-item-value-type {\r
+ description\r
+ "The value type of the match item.";\r
default string;\r
type enumeration {\r
enum string {\r
- description "A string-valued match item";\r
+ description\r
+ "A string-valued match item.";\r
}\r
enum int {\r
- description "An integer-valued match item";\r
+ description\r
+ "An integer-valued match item.";\r
}\r
enum range {\r
- description "An integer-range match item";\r
+ description\r
+ "An integer-range match item.";\r
}\r
}\r
}\r
- leaf is-required {\r
- description "Specify whether the match item is required \r
- for the flow.";\r
- default optional;\r
- type enumeration {\r
- enum required {\r
- description "The match item is required";\r
- }\r
- enum optional {\r
- description "The match item is optional";\r
- }\r
+ }\r
+ }\r
+\r
+ container flow-property-definitions {\r
+ description\r
+ "Contains the property definitions for the flow.";\r
+\r
+ uses property-definitions;\r
+ }\r
+\r
+ grouping property-instance {\r
+ description\r
+ "The property instance and its associated metadata.";\r
+\r
+ leaf property-name {\r
+ description\r
+ "The name for the property which can be seen as a unique\r
+ identifier of the property.";\r
+ type nemo-common:property-name;\r
+ mandatory true;\r
+ }\r
+\r
+ container property-values {\r
+ description\r
+ "The value list of the property.";\r
+\r
+ list string-value {\r
+ key "value order";\r
+ leaf value {\r
+ type string;\r
+ }\r
+\r
+ leaf order {\r
+ type uint32;\r
}\r
}\r
- } \r
- } \r
- container flow-definitions{\r
- list flow-definition{\r
- key "id";\r
- leaf id {\r
- description "A unique ID for a kind of flow definition";\r
- type nemo-common:flow-definition-id;\r
- mandatory true;\r
- } \r
- leaf flow-type{\r
- description "A user-readable description";\r
- type nemo-common:flow-definition-type;\r
- mandatory true; \r
- }\r
- uses match-item-definition; \r
- } \r
- }\r
- \r
- grouping node-property-instance{\r
- list property {\r
- key "name";\r
- leaf name {\r
- type nemo-common:node-property-name;\r
- mandatory true;\r
- }\r
- leaf string-value {\r
- type string;\r
- }\r
- leaf int-value {\r
- type int64;\r
- }\r
- container range-value {\r
- leaf min {\r
+\r
+ list int-value {\r
+ key "value order";\r
+ leaf value {\r
type int64;\r
- mandatory true;\r
}\r
- leaf max {\r
- type int64;\r
- mandatory true;\r
+\r
+ leaf order {\r
+ type uint32;\r
}\r
}\r
- } \r
- } \r
- grouping node-instance{\r
- description "";\r
- leaf node-id {\r
- description "A unique ID for the node instance";\r
- type nemo-common:node-instance-id;\r
- mandatory true;\r
- }\r
- leaf node-name {\r
- description\r
- "A user-visible name for the node definition";\r
- type nemo-common:node-instance-name;\r
- }\r
- leaf node-type {\r
- type nemo-common:node-instance-type;\r
- mandatory true; \r
- }\r
- container subnodes{ \r
- leaf-list subnode-id{\r
- type nemo-common:node-instance-id; \r
- } \r
- }\r
- container property{\r
- uses node-property-instance; \r
- } \r
- }\r
- \r
- grouping connection-property-instance{\r
- list property {\r
- key "name";\r
- leaf name {\r
- type nemo-common:connection-property-name;\r
- mandatory true;\r
- }\r
- leaf string-value {\r
- type string;\r
- }\r
- leaf int-value {\r
- type int64;\r
- }\r
+\r
container range-value {\r
leaf min {\r
type int64;\r
mandatory true;\r
}\r
+\r
leaf max {\r
type int64;\r
mandatory true;\r
}\r
}\r
- } \r
- } \r
- grouping connection-instance {\r
- description "";\r
- leaf connection-id {\r
- description "A unique ID for the connection instance";\r
- type nemo-common:connection-instance-id;\r
- mandatory true;\r
- }\r
- leaf connection-name {\r
- description "A user-visible name for the connection instance";\r
- type nemo-common:connection-instance-name;\r
- mandatory false;\r
- }\r
- leaf connection-type {\r
- type nemo-common:connection-instance-type;\r
- mandatory true; \r
- }\r
- container endnodes{\r
- list one-end{\r
- key "node-id";\r
- leaf node-id{\r
- type nemo-common:node-instance-id; \r
- }\r
- min-elements 1;\r
- } \r
- list the-other-end{\r
- key "node-id";\r
- leaf node-id{\r
- type nemo-common:node-instance-id;\r
- }\r
- min-elements 1; \r
- } \r
- }\r
- container property{\r
- uses connection-property-instance; \r
- } \r
- }\r
- \r
- grouping match-item-instance{\r
- list match-item {\r
- key "name";\r
- leaf name {\r
- type string;\r
- mandatory true;\r
+ }\r
+ }\r
+\r
+ grouping node-instance {\r
+ description\r
+ "It represents the node instance and its metadata.\r
+ A node represents the functions a network node may provide in a\r
+ network such as network services,or a group of network elements.";\r
+\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for a node instance";\r
+ type nemo-common:node-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf node-name {\r
+ description\r
+ "A user-visible and unique name for a node instance.";\r
+ type nemo-common:node-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf node-type {\r
+ description\r
+ "A user-visible and unique type identifier for a node instance.";\r
+ type nemo-common:node-type;\r
+ mandatory true;\r
+ }\r
+\r
+ list sub-node {\r
+ description\r
+ "Represents the sub-nodes which have been included\r
+ by the node instance logically.";\r
+\r
+ key "node-id";\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for a node instance.";\r
+ type nemo-common:node-id;\r
+ }\r
+\r
+ leaf order {\r
+ description\r
+ "Specify the order of the node in a sequence node list.";\r
+ type uint32;\r
+ }\r
+ }\r
+\r
+ list property {\r
+ description\r
+ "The property list of a node instance.";\r
+\r
+ key "property-name";\r
+ uses property-instance;\r
+ }\r
+ }\r
+\r
+ grouping connection-instance {\r
+ description\r
+ "It represents the connection instance and its metadata.\r
+ The Connection describes the resource between node entities.\r
+ This connection is not limited to any physical link, but just\r
+ expresses the communication capacity between nodes.";\r
+\r
+ leaf connection-id {\r
+ description\r
+ "A unique ID for a connection instance.";\r
+ type nemo-common:connection-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf connection-name {\r
+ description\r
+ "A user-visible and unique name for a connection instance.";\r
+ type nemo-common:connection-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf connection-type {\r
+ description\r
+ "A user-visible and unique type identifier for a connection instance.";\r
+ type nemo-common:connection-type;\r
+ mandatory true;\r
+ }\r
+\r
+ list end-node {\r
+ description\r
+ "Represents the nodes which will be connected by connection.\r
+ At least two nodes in the list.";\r
+\r
+ key "node-id";\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for a node instance.";\r
+ type nemo-common:node-id;\r
+ }\r
+\r
+ leaf order {\r
+ description\r
+ "Specify the order of the node in a sequence node list";\r
+ type uint32;\r
}\r
+\r
+ min-elements 2;\r
+ }\r
+\r
+ list property {\r
+ description\r
+ "The property list of a connection instance.";\r
+\r
+ key "property-name";\r
+ uses property-instance;\r
+ }\r
+ }\r
+\r
+ grouping match-item-instance {\r
+ description\r
+ "Represents the match item and its metadata.";\r
+\r
+ leaf match-item-name {\r
+ description\r
+ "A name for a match item.";\r
+ type nemo-common:match-item-name;\r
+ mandatory true;\r
+ }\r
+\r
+ container match-item-value {\r
+ description\r
+ "The value of a match item.";\r
+\r
leaf string-value {\r
type string;\r
}\r
+\r
leaf int-value {\r
type int64;\r
}\r
+\r
container range-value {\r
leaf min {\r
type int64;\r
mandatory true;\r
}\r
+\r
leaf max {\r
type int64;\r
mandatory true;\r
}\r
}\r
- } \r
- }\r
- grouping has-direction {\r
- description "Object that have a directionality."; \r
- leaf direction {\r
- default bidirectional;\r
- type enumeration {\r
- enum in {\r
- description\r
- "Applies to flow into provider node";\r
- }\r
- enum out {\r
- description\r
- "Applies to flow out of provider node";\r
- }\r
- enum bidirectional {\r
- description\r
- "Applies to flow in both directions";\r
- }\r
- }\r
}\r
- } \r
- grouping flow-instance{\r
- leaf flow-id {\r
- description "A unique ID for the flow instance";\r
- type nemo-common:flow-instance-id;\r
- mandatory true;\r
- }\r
- leaf flow-name {\r
- description "A user-visible name for the flow instance";\r
- type nemo-common:flow-instance-name;\r
- mandatory false;\r
- }\r
- leaf flow-type {\r
- type nemo-common:flow-instance-type;\r
- mandatory true; \r
- }\r
- container match {\r
- uses has-direction;\r
- uses match-item-instance;\r
- }\r
- } \r
- \r
+ }\r
+\r
+ grouping flow-instance {\r
+ description\r
+ "Represents the flow instance and its metadata.\r
+ The flow refers to the traffic in network which describes\r
+ data packets have some certain characters.";\r
+\r
+ leaf flow-id {\r
+ description\r
+ "A unique ID for a flow instance.";\r
+ type nemo-common:flow-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf flow-name {\r
+ description\r
+ "A user-visible and unique name for a flow instance.";\r
+ type nemo-common:flow-name;\r
+ mandatory true;\r
+ }\r
+\r
+ list match-item {\r
+ description\r
+ "The match item list of a flow instance.";\r
+\r
+ key "match-item-name";\r
+ uses match-item-instance;\r
+ }\r
+\r
+ list property {\r
+ description\r
+ "The property list of a flow instance.";\r
+\r
+ key "property-name";\r
+ uses property-instance;\r
+ }\r
+ }\r
}\r
/*\r
- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
*\r
* This program and the accompanying materials are made available under the\r
* terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
*/\r
\r
module nemo-operation {\r
+ yang-version 1;\r
\r
- yang-version 1; \r
- namespace "urn:opendaylight:params:xml:ns:yang:nemo:operation"; \r
- prefix "nemo-operation";\r
- \r
- import nemo-common {prefix nemo-common;}\r
- \r
- revision "2015-06-29" {\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:operation";\r
+ prefix "nemo-operation";\r
+\r
+ import nemo-common {prefix nemo-common;}\r
+\r
+ revision "2015-10-10" {\r
description\r
"Initial revision.";\r
}\r
- \r
- grouping parameter-definition {\r
- leaf name {\r
- description "A user-visible name for parameter";\r
- type nemo-common:parameter-name;\r
- mandatory true;\r
- } \r
- leaf type {\r
- description "The type of the parameter";\r
- default string;\r
- type enumeration {\r
- enum string {\r
- description "A string-valued parameter";\r
- }\r
- enum int {\r
- description "An integer-valued parameter";\r
- }\r
- enum range {\r
- description "An integer-range parameter";\r
- }\r
- }\r
- } \r
- leaf is-required {\r
- description "Specify whether the parameter is required ";\r
- default optional;\r
- type enumeration {\r
- enum required {\r
- description "The parameter is required";\r
- }\r
- enum optional {\r
- description "The parameter is optional";\r
- }\r
- }\r
- } \r
- }\r
- \r
- \r
- container action-definitions {\r
- list action-definition { \r
- key "action-name";\r
- leaf action-name {\r
- description "A name for the action definition";\r
- type nemo-common:action-definition-name;\r
- mandatory true; \r
- } \r
- list data {\r
- description\r
- "data for the action that can be passed in.";\r
- key "name"; \r
- uses parameter-definition; \r
- } \r
- }\r
- } \r
- grouping action-parameter-instance{\r
- leaf data-name {\r
- type nemo-common:data-name;\r
- mandatory true;\r
- }\r
- leaf string-value {\r
- type string;\r
- }\r
- leaf int-value {\r
- type int64;\r
- }\r
- container range-value {\r
- leaf min {\r
- type int64;\r
- mandatory true;\r
- }\r
- leaf max {\r
- type int64;\r
- mandatory true;\r
- }\r
- } \r
- } \r
- grouping action-instance{\r
- description " ";\r
- leaf action-name{\r
- type nemo-common:action-instance-name;\r
- mandatory true;\r
- }\r
- list data {\r
- key "data-name";\r
- uses action-parameter-instance; \r
- } \r
- }\r
- \r
- container condition-definitions {\r
- list condition-definition{\r
- key "condition-name";\r
- leaf condition-name{\r
- type nemo-common:condition-definition-name;\r
- mandatory true; \r
- }\r
- list condition-parameter{\r
- key "name";\r
- uses parameter-definition;\r
- min-elements 1;\r
- } \r
- }\r
- }\r
- grouping conditon-parameter-instance{\r
- leaf parameter-name {\r
- type nemo-common:condition-parameter-name;\r
- mandatory true;\r
- }\r
- leaf string-value {\r
- type string;\r
- }\r
- leaf int-value {\r
- type int64;\r
- }\r
- container range-value {\r
- leaf min {\r
- type int64;\r
- mandatory true;\r
- }\r
- leaf max {\r
- type int64;\r
- mandatory true;\r
- }\r
- } \r
- } \r
- grouping condition-instance {\r
- description " ";\r
- leaf condition-name{\r
- type nemo-common:condition-instance-name;\r
- mandatory true; \r
- } \r
- list condition-parameter{\r
- key "parameter-name";\r
- uses conditon-parameter-instance;\r
- min-elements 1;\r
- }\r
- }\r
- \r
- \r
- container constraint-definitions {\r
- list constraint-definition{\r
- key "constraint-name";\r
- leaf constraint-name{\r
- type nemo-common:constraint-definition-name;\r
- mandatory true; \r
- }\r
- list constraint-parameter{\r
- key "name";\r
- uses parameter-definition;\r
- min-elements 1;\r
- } \r
- }\r
- }\r
- grouping constraint-parameter-instance{\r
- leaf parameter-name {\r
- type nemo-common:constraint-parameter-name;\r
- mandatory true;\r
- }\r
- leaf string-value {\r
- type string;\r
- }\r
- leaf int-value {\r
- type int64;\r
- }\r
- container range-value {\r
- leaf min {\r
- type int64;\r
- mandatory true;\r
- }\r
- leaf max {\r
- type int64;\r
- mandatory true;\r
- }\r
- } \r
- } \r
- grouping constraint-instance {\r
- description " ";\r
- leaf constraint-name{\r
- type nemo-common:constraint-instance-name;\r
- mandatory true; \r
- } \r
- list constraint-parameter{\r
- key "parameter-name";\r
- uses constraint-parameter-instance;\r
- min-elements 1;\r
- }\r
- }\r
- \r
-}
\ No newline at end of file
+\r
+ container condition-parameter-definitions {\r
+ list condition-parameter-definition {\r
+ description\r
+ "Defines the condition parameter with its metadata.";\r
+\r
+ key "parameter-name";\r
+ leaf parameter-name {\r
+ description\r
+ "A name for the condition parameter.";\r
+ type nemo-common:parameter-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf parameter-value-type {\r
+ description\r
+ "A type of value for the condition parameter.";\r
+ type enumeration {\r
+ enum string {\r
+ description\r
+ "A string-valued parameter.";\r
+ }\r
+ enum int {\r
+ description\r
+ "An integer-valued parameter.";\r
+ }\r
+ enum range {\r
+ description\r
+ "An integer-range parameter.";\r
+ }\r
+ }\r
+ }\r
+\r
+ container parameter-match-patterns {\r
+ description\r
+ "Defines the match patterns of the condition parameter.";\r
+\r
+ leaf-list parameter-match-pattern {\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ enum periodical;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ container action-definitions {\r
+ list action-definition {\r
+ description\r
+ "Defines the actions which will be supported by the NEMO project.";\r
+\r
+ key "action-name";\r
+ leaf action-name {\r
+ description\r
+ "A name for the action definition.";\r
+ type nemo-common:action-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf parameter-value-type {\r
+ description\r
+ "The type of the action parameter.";\r
+ default string;\r
+ type enumeration {\r
+ enum string {\r
+ description\r
+ "A string-valued parameter.";\r
+ }\r
+ enum int {\r
+ description\r
+ "An integer-valued parameter.";\r
+ }\r
+ enum range {\r
+ description\r
+ "An integer-range parameter.";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping condition-instance {\r
+ description\r
+ "Specific a instance of condition whose metadata has been filled in.";\r
+\r
+ list condition-segment {\r
+ description\r
+ "The segment entities will be composed into a whole condition entity.\r
+ Each segment will be a sub expression of the condition.";\r
+\r
+ key "condition-segment-id";\r
+ leaf condition-segment-id {\r
+ description\r
+ "A unique ID for a condition segment.";\r
+ type nemo-common:condition-segment-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf condition-parameter-name {\r
+ description\r
+ "A name for a conditon parameter.";\r
+ type nemo-common:condition-parameter-name;\r
+ }\r
+\r
+ leaf condition-parameter-match-pattern {\r
+ description\r
+ "The operator for the condition parameter and it's target value.";\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ enum periodical;\r
+ }\r
+ }\r
+\r
+ container condition-parameter-target-value {\r
+ description\r
+ "The target value of condition parameter.";\r
+\r
+ leaf string-value {\r
+ type string;\r
+ }\r
+\r
+ leaf int-value {\r
+ type int64;\r
+ }\r
+\r
+ container range-value {\r
+ leaf min {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf max {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+ }\r
+ }\r
+\r
+ leaf precursor-relation-operator {\r
+ description\r
+ "The logical operator between current segment and the next segment.";\r
+ type enumeration {\r
+ enum none;\r
+ enum and;\r
+ enum or;\r
+ enum not;\r
+ }\r
+ }\r
+\r
+ leaf order {\r
+ description\r
+ "The order of the segment in the whole condition entity.";\r
+ type uint32;\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping action-instance {\r
+ description\r
+ "Specific a action instance whose metadata has been filled in.";\r
+\r
+ leaf action-name {\r
+ description\r
+ "A name for a action instance.";\r
+ type nemo-common:action-name;\r
+ mandatory true;\r
+ }\r
+\r
+ container parameter-values {\r
+ description\r
+ "The parameter value list of an action.";\r
+\r
+ list string-value {\r
+ key "value order";\r
+ leaf value {\r
+ type string;\r
+ }\r
+\r
+ leaf order {\r
+ type uint32;\r
+ }\r
+ }\r
+\r
+ list int-value {\r
+ key "value order";\r
+ leaf value {\r
+ type int64;\r
+ }\r
+\r
+ leaf order {\r
+ type uint32;\r
+ }\r
+ }\r
+\r
+ container range-value {\r
+ leaf min {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf max {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping operation-instance {\r
+ description\r
+ "Specific an operation instance whose metadata has been filled in.\r
+ Operation is a type of intent which refers to taking for some specific\r
+ actions to realize the purpose.";\r
+\r
+ leaf operation-id {\r
+ description\r
+ "A unique ID for a operation instance.";\r
+ type nemo-common:operation-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf operation-name {\r
+ description\r
+ "A user-visible and unique name for a operation instance.";\r
+ type nemo-common:operation-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf priority {\r
+ description\r
+ "Defines the priority of a operation instance.";\r
+ type uint32;\r
+ default 0;\r
+ }\r
+\r
+ leaf target-object {\r
+ description\r
+ "The target object which the operation instance will apply to.";\r
+ type nemo-common:object-id;\r
+ mandatory true;\r
+ }\r
+\r
+ uses condition-instance;\r
+\r
+ list action {\r
+ description\r
+ "The action list for the operation instance.";\r
+\r
+ key "action-name";\r
+ uses action-instance;\r
+\r
+ leaf order {\r
+ description\r
+ "The order of an action instance in execution sequence.";\r
+ type uint32;\r
+ }\r
+\r
+ min-elements 1;\r
+ }\r
+ }\r
+}\r
/*\r
- * Copyright (c) 2015 Huawei Technologies Co., Ltd. and others. All rights reserved.\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
*\r
* This program and the accompanying materials are made available under the\r
* terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
* and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
\r
-module nemo-result{\r
+module nemo-result {\r
+ yang-version 1;\r
\r
- yang-version 1; \r
- namespace "urn:opendaylight:params:xml:ns:yang:nemo:result"; \r
- prefix "nemo-result";\r
- \r
- import nemo-common {prefix nemo-common;}\r
- \r
- revision "2015-06-29" {\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:result";\r
+ prefix "nemo-result";\r
+\r
+ import nemo-common {prefix nemo-common;}\r
+\r
+ revision "2015-10-10" {\r
description\r
"Initial revision.";\r
}\r
- \r
- container expected-definitons{\r
- \r
- } \r
- \r
- grouping expected-instance {\r
- leaf expected-id {\r
- type nemo-common:expected-instance-id;\r
- mandatory true;\r
- }\r
- leaf expected-name{\r
- type nemo-common:expected-instance-name;\r
- mandatory false;\r
- }\r
- leaf expected-description {\r
- type nemo-common:description;\r
- } \r
- }\r
- \r
- container avoid-definitons{\r
- \r
- }\r
\r
- grouping avoid-instance {\r
- leaf avoid-id {\r
- type nemo-common:avoid-instance-id;\r
- mandatory true;\r
- }\r
- leaf avoid-name{\r
- type nemo-common:avoid-instance-name;\r
- mandatory false;\r
- }\r
- leaf avoid-description {\r
- type nemo-common:description;\r
- } \r
- }\r
- \r
-}
\ No newline at end of file
+ // TBD\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module nemo-user {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:user";\r
+ prefix "nemo-user";\r
+\r
+ import nemo-common {prefix nemo-common;}\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ container user-roles {\r
+ list user-role {\r
+ description\r
+ "Defines the user role. Different users have different\r
+ intention manifestations, which have different granularity\r
+ or different level. It depends on users' role, knowledge\r
+ and their purpose.";\r
+\r
+ key "role-name";\r
+ leaf role-name {\r
+ description\r
+ "A user-visible and unique name for a kind of role.";\r
+ type nemo-common:user-role-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf role-description {\r
+ description\r
+ "Describes the characteristic,responsibility and purpose for a kind of role.";\r
+ type nemo-common:user-role-description;\r
+ }\r
+\r
+ // TBD\r
+ }\r
+ }\r
+\r
+ grouping user-instance {\r
+ description\r
+ "It represents an instance of the user.";\r
+\r
+ leaf user-id {\r
+ description\r
+ "A unique ID for a user.";\r
+ type nemo-common:user-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf user-name {\r
+ description\r
+ "A user-visible and unique name for the user.";\r
+ type nemo-common:user-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf user-password {\r
+ description\r
+ "The password of a user.";\r
+ type nemo-common:user-password;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf user-role {\r
+ description\r
+ "The role of a user.";\r
+ type nemo-common:user-role-name;\r
+ mandatory true;\r
+ }\r
+ }\r
+}\r
</prerequisites>
<properties>
- <controller.mdsal.version>1.3.0-SNAPSHOT</controller.mdsal.version>
<mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
+ <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
<restconf.version>1.3.0-SNAPSHOT</restconf.version>
<dlux.version>0.3.0-SNAPSHOT</dlux.version>
+ <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
</properties>
<dependencyManagement>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>mdsal-artifacts</artifactId>
- <version>${controller.mdsal.version}</version>
+ <version>${mdsal.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<type>xml</type>
<scope>runtime</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>features-openflowplugin</artifactId>
+ <version>${openflowplugin.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>features-openflowplugin-extension</artifactId>
+ <version>${openflowplugin.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ </dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nemo-api</artifactId>
<artifactId>nemo-impl</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>nemo-impl</artifactId>
+ <version>${project.version}</version>
+ <classifier>config</classifier>
+ <type>xml</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>openflow-renderer</artifactId>
<classifier>config</classifier>
<type>xml</type>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openflow-renderer</artifactId>
+ <version>${project.version}</version>
+ <classifier>resource</classifier>
+ <type>json</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nemo-ui</artifactId>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">\r
<repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>\r
- <repository>mvn:org.opendaylight.controller/features-mdsal/${controller.mdsal.version}/xml/features</repository>\r
+ <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>\r
<repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>\r
<repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>\r
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>\r
+ <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/${openflowplugin.version}/xml/features</repository>\r
<feature name='odl-nemo-api' version='${project.version}' description='OpenDaylight :: NEMO :: API'>\r
<feature version='${mdsal.model.version}'>odl-mdsal-models</feature>\r
<bundle>mvn:org.opendaylight.nemo/nemo-api/${project.version}</bundle>\r
</feature>\r
<feature name='odl-nemo-engine' version='${project.version}' description='OpenDaylight :: NEMO :: Engine'>\r
- <feature version='${controller.mdsal.version}'>odl-mdsal-broker</feature>\r
+ <feature version='${mdsal.version}'>odl-mdsal-broker</feature>\r
<feature version='${project.version}'>odl-nemo-api</feature>\r
<bundle>mvn:org.opendaylight.nemo/nemo-impl/${project.version}</bundle>\r
+ <configfile finalname='etc/opendaylight/karaf/00-nemo-engine.xml'>mvn:org.opendaylight.nemo/nemo-impl/${project.version}/xml/config</configfile>\r
</feature>\r
<feature name='odl-nemo-engine-rest' version='${project.version}' description='OpenDaylight :: NEMO :: Engine :: REST'>\r
<feature version='${restconf.version}'>odl-restconf</feature>\r
- <feature version='${restconf.version}'>odl-mdsal-apidocs</feature>\r
- <feature version='${controller.mdsal.version}'>odl-mdsal-xsql</feature>\r
+ <feature version='${mdsal.version}'>odl-mdsal-apidocs</feature>\r
+ <feature version='${mdsal.version}'>odl-mdsal-xsql</feature>\r
<feature version='${project.version}'>odl-nemo-engine</feature>\r
</feature>\r
<feature name='odl-nemo-openflow-renderer' version='${project.version}' description='OpenDaylight :: NEMO :: OpenFlow Renderer'>\r
- <feature version='${project.version}'>odl-nemo-engine</feature>\r
+ <feature version='${openflowplugin.version}'>odl-openflowplugin-flow-services</feature>\r
+ <feature version='${openflowplugin.version}'>odl-openflowplugin-nxm-extensions</feature>\r
+ <feature version='${project.version}'>odl-nemo-engine-rest</feature>\r
<bundle>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}</bundle>\r
- <configfile finalname='etc/opendaylight/karaf/00-nemo-openflow-renderer.xml'>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}/xml/config</configfile>\r
+ <configfile finalname='etc/opendaylight/karaf/01-nemo-openflow-renderer.xml'>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}/xml/config</configfile>\r
+ <configfile finalname='etc/nemo/nemo-openflow-renderer-resource.json'>mvn:org.opendaylight.nemo/openflow-renderer/${project.version}/json/resource</configfile>\r
+ </feature>\r
+ <feature name='odl-nemo-cli-renderer' version='${project.version}' description='OpenDaylight :: NEMO :: CLI Renderer'>\r
+ <feature version='${project.version}'>odl-nemo-engine-rest</feature>\r
</feature>\r
<feature name='odl-nemo-engine-ui' version='${project.version}' description='OpenDaylight :: NEMO :: Engine :: UI'>\r
<feature version='${dlux.version}'>odl-dlux-core</feature>\r
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.opendaylight.mdsal</groupId>
- <artifactId>binding-parent</artifactId>
- <version>0.8.0-SNAPSHOT</version>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-parent</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
<relativePath />
</parent>
<properties>
<jacoco.version>0.7.2.201409121644</jacoco.version>
+ <sonar.jacoco.reportPath>target/code-coverage/jacoco.exec</sonar.jacoco.reportPath>
+ <sonar.jacoco.itReportPath>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
</properties>
<dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types</artifactId>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nemo-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>net.sourceforge.collections</groupId>
+ <artifactId>collections-generic</artifactId>
+ <version>4.01</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.jung</groupId>
+ <artifactId>jung-api</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.jung</groupId>
+ <artifactId>jung-graph-impl</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.jung</groupId>
+ <artifactId>jung-algorithms</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</pluginManagement>
<plugins>
<plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <yangFilesRootDir>src/main/yang</yangFilesRootDir>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${yangtools.version}</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
<configuration>
- <includes>
- <include>org.opendaylight.nemo.*</include>
- </includes>
+ <instructions>
+ <Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
+ <Import-Package>*;resolution:=optional</Import-Package>
+ <Embed-Dependency>
+ collections-generic,jung-api,jung-graph-impl,jung-algorithms
+ </Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Embed-Directory>lib</Embed-Directory>
+ <Embed-StripGroup>true</Embed-StripGroup>
+ <_failok>true</_failok>
+ <_nouses>true</_nouses>
+ </instructions>
+ <manifestLocation>${project.build.outputDirectory}/META-INF</manifestLocation>
</configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/etc/opendaylight/karaf/config.xml</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
- <id>pre-test</id>
+ <id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
+ <configuration>
+ <destFile>${sonar.jacoco.reportPath}</destFile>
+ </configuration>
</execution>
<execution>
- <id>post-test</id>
+ <id>post-unit-test</id>
<goals>
<goal>report</goal>
</goals>
- <phase>test</phase>
+ <configuration>
+ <dataFile>${sonar.jacoco.reportPath}</dataFile>
+ </configuration>
</execution>
</executions>
</plugin>
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLinkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPortBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResultBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResource;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResourceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+/**\r
+ * Resolve the user's connection intent. Create the virtual link according\r
+ * to the connection if necessary, and then map the created virtual link\r
+ * into the physical network. Finally, store these intent mapping results\r
+ * into the data store.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class ConnectionMapper {\r
+ private static final Logger LOG = LoggerFactory.getLogger(ConnectionMapper.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ /**\r
+ * The node mapper to resolve the user's node intent.\r
+ */\r
+ private NodeMapper nodeMapper;\r
+\r
+ public ConnectionMapper(DataBroker dataBroker, NodeMapper nodeMapper) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+ this.nodeMapper = nodeMapper;\r
+\r
+ LOG.debug("Initialized the renderer common connection mapper.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Resolve the user's connection intent, perform the intent mapping\r
+ * if necessary, and store the intent mapping results into data store.\r
+ *\r
+ * @param user The user for the connection.\r
+ * @param connection The connection to be resolved.\r
+ * @param virtualNetwork The virtual network for the user.\r
+ * @param userIntentVnMapping The intent-vn mapping for the user.\r
+ */\r
+ protected void resolveConnection(User user, Connection connection,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ ConnectionType connectionType = connection.getConnectionType();\r
+\r
+ if ( connectionType.equals(new ConnectionType("p2p")) ) {\r
+ resolveP2PConnection(user, connection, virtualNetwork, userIntentVnMapping, false, true, true);\r
+\r
+ return;\r
+ }\r
+\r
+ if ( connectionType.equals(new ConnectionType("p2mp")) ) {\r
+ resolveP2MPConnection(user, connection, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ if ( connectionType.equals(new ConnectionType("mesh")) ) {\r
+ resolveMeshConnection(user, connection, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ throw new IntentResolutionException("Unknown connection type.");\r
+\r
+// return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnection(User user, Connection connection,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ List<Node> nodes = user.getObjects().getNode();\r
+ NodeId nodeId = connection.getEndNode().get(0).getNodeId();\r
+ Node endNode1 = IntentResolverUtils.getNode(nodes, nodeId);\r
+\r
+ if ( null == endNode1 ) {\r
+ throw new IntentResolutionException("The end-node " + nodeId.getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " does not exist.");\r
+ }\r
+\r
+ nodeId = connection.getEndNode().get(1).getNodeId();\r
+ Node endNode2 = IntentResolverUtils.getNode(nodes, nodeId);\r
+\r
+ if ( null == endNode2 ) {\r
+ throw new IntentResolutionException("The end-node " + nodeId.getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " does not exist.");\r
+ }\r
+\r
+ NodeType hostNodeType = new NodeType("host");\r
+ NodeType layer2GroupNodeType = new NodeType("l2-group");\r
+ NodeType layer3GroupNodeType = new NodeType("l3-group");\r
+ NodeType externalGroupNodeType = new NodeType("ext-group");\r
+ NodeType serviceChainGroupNodeType = new NodeType("chain-group");\r
+ NodeType firewallNodeType = new NodeType("fw");\r
+ NodeType loadbalancerNodeType = new NodeType("lb");\r
+ NodeType cacheNodeType = new NodeType("cache");\r
+\r
+ if ( endNode1.getNodeType().equals(hostNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode1.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be host type.");\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(layer2GroupNodeType) ) {\r
+ if ( endNode2.getNodeType().equals(hostNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be host type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(layer2GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer2Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(layer3GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer2AndLayer3Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(externalGroupNodeType) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(endNode2) ) {\r
+ return resolveP2PConnectionBetweenLayer2AndExternalLayer3Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ } else {\r
+ return resolveP2PConnectionBetweenLayer2AndExternalLayer2Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(serviceChainGroupNodeType) ) {\r
+ return null;\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(firewallNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be fw type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(loadbalancerNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be lb type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(cacheNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be cache type.");\r
+ }\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(layer3GroupNodeType) ) {\r
+ if ( endNode2.getNodeType().equals(hostNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be host type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(layer2GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer2AndLayer3Groups(user, connection,\r
+ endNode2, endNode1, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(layer3GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer3Groups(user, connection, endNode1,\r
+ endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(externalGroupNodeType) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(endNode2) ) {\r
+ return resolveP2PConnectionBetweenLayer3AndExternalLayer3Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ } else {\r
+ return resolveP2PConnectionBetweenLayer3AndExternalLayer2Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(serviceChainGroupNodeType) ) {\r
+ return null;\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(firewallNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be fw type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(loadbalancerNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be lb type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(cacheNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be cache type.");\r
+ }\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(externalGroupNodeType) ) {\r
+ if ( endNode2.getNodeType().equals(hostNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be host type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(serviceChainGroupNodeType) ) {\r
+ return null;\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(firewallNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be fw type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(loadbalancerNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be lb type.");\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(cacheNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode2.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be cache type.");\r
+ }\r
+\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(endNode1) ) {\r
+ if ( endNode2.getNodeType().equals(layer2GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer2AndExternalLayer3Groups(user, connection,\r
+ endNode2, endNode1, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(layer3GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer3AndExternalLayer3Groups(user, connection,\r
+ endNode2, endNode1, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(externalGroupNodeType) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(endNode2) ) {\r
+ return resolveP2PConnectionBetweenExternalLayer3Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ } else {\r
+ return resolveP2PConnectionBetweenExternalLayer2AndLayer3Groups(user, connection,\r
+ endNode2, endNode1, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+ }\r
+ } else {\r
+ if ( endNode2.getNodeType().equals(layer2GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer2AndExternalLayer2Groups(user, connection,\r
+ endNode2, endNode1, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(layer3GroupNodeType) ) {\r
+ return resolveP2PConnectionBetweenLayer3AndExternalLayer2Groups(user, connection,\r
+ endNode2, endNode1, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+\r
+ if ( endNode2.getNodeType().equals(externalGroupNodeType) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(endNode2) ) {\r
+ return resolveP2PConnectionBetweenExternalLayer2AndLayer3Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ } else {\r
+ return resolveP2PConnectionBetweenExternalLayer2Groups(user, connection,\r
+ endNode1, endNode2, virtualNetwork, userIntentVnMapping,\r
+ tempConnection, resolvingEndNode1, resolvingEndNode2);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(serviceChainGroupNodeType) ) {\r
+ return null;\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(firewallNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode1.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be fw type.");\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(loadbalancerNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode1.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be lb type.");\r
+ }\r
+\r
+ if ( endNode1.getNodeType().equals(cacheNodeType) ) {\r
+ throw new IntentResolutionException("The end-node " + endNode1.getNodeId().getValue() +\r
+ " of the connection " + connection.getConnectionId().getValue() +\r
+ " can not be cache type.");\r
+ }\r
+\r
+ throw new IntentResolutionException("Unknown node type for the end-nodes of the connection " +\r
+ connection.getConnectionId().getValue() + ".");\r
+\r
+// return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ private void resolveP2MPConnection(User user, Connection connection,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ // TODO: 1、注意root是external layer2 group的情况,只能映射一次。\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ private void resolveMeshConnection(User user, Connection connection,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ // TODO: 1、注意各个end node是external layer2 group的情况,只能映射一次。\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer2Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ IntentVnMappingResult intentVnMappingResult1 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult1 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult2 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult2 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(intentVnMappingResult1.getVirtualResource().get(0)\r
+ .getVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(intentVnMappingResult2.getVirtualResource().get(0)\r
+ .getVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property property = IntentResolverUtils\r
+ .getConnectionProperty(connection.getProperty(), new PropertyName("bandwidth"));\r
+ long bandwidth = 0;\r
+\r
+ if ( null != property ) {\r
+ bandwidth = /*1024 * */property.getPropertyValues().getIntValue().get(0).getValue();\r
+ }\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter1.getVirtualPort().add(virtualPort1);\r
+\r
+ VirtualPort virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter2.getVirtualPort().add(virtualPort2);\r
+\r
+ VirtualLink virtualLink1 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter2.getNodeId())\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ VirtualLink virtualLink2 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter2.getNodeId())\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualRouter1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+\r
+ if ( tempConnection ) {\r
+ List<VirtualLink> virtualLinks = new ArrayList<VirtualLink>(2);\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ return virtualLinks;\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(2);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(connection.getConnectionId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Connection)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer2AndLayer3Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ // TODO: l2-group - l3-group: 创建l2-group的gw vrouter与l3-group的sub-nodes的gw/acc vrouters间的vlinks(vports)。\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer2AndExternalLayer2Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ if ( resolvingEndNode2 ) {\r
+ nodeMapper.resolveExternalLayer2Group(user, endNode2, virtualNetwork, userIntentVnMapping, true);\r
+ }\r
+\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ IntentVnMappingResult intentVnMappingResult1 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult1 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult2 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult2 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(intentVnMappingResult1.getVirtualResource().get(0)\r
+ .getVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(intentVnMappingResult2.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property property = IntentResolverUtils\r
+ .getConnectionProperty(connection.getProperty(), new PropertyName("bandwidth"));\r
+ long bandwidth = 0;\r
+\r
+ if ( null != property ) {\r
+ bandwidth = /*1024 * */property.getPropertyValues().getIntValue().get(0).getValue();\r
+ }\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter1.getVirtualPort().add(virtualPort1);\r
+\r
+ VirtualPort virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter2.getVirtualPort().add(virtualPort2);\r
+\r
+ VirtualLink virtualLink1 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter2.getNodeId())\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ VirtualLink virtualLink2 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter2.getNodeId())\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualRouter1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+\r
+ if ( tempConnection ) {\r
+ List<VirtualLink> virtualLinks = new ArrayList<VirtualLink>(2);\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ return virtualLinks;\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(2);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(connection.getConnectionId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Connection)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer2AndExternalLayer3Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ IntentVnMappingResult intentVnMappingResult1 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult1 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult2 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult2 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(intentVnMappingResult1.getVirtualResource().get(0)\r
+ .getVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(intentVnMappingResult2.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property property = IntentResolverUtils\r
+ .getConnectionProperty(connection.getProperty(), new PropertyName("bandwidth"));\r
+ long bandwidth = 0;\r
+\r
+ if ( null != property ) {\r
+ bandwidth = /*1024 * */property.getPropertyValues().getIntValue().get(0).getValue();\r
+ }\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter1.getVirtualPort().add(virtualPort1);\r
+\r
+ VirtualPort virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter2.getVirtualPort().add(virtualPort2);\r
+\r
+ VirtualLink virtualLink1 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter2.getNodeId())\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ VirtualLink virtualLink2 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter2.getNodeId())\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualRouter1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+\r
+ if ( tempConnection ) {\r
+ List<VirtualLink> virtualLinks = new ArrayList<VirtualLink>(2);\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ return virtualLinks;\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(2);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(connection.getConnectionId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Connection)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer3Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ // TODO: l3-group - l3-group: 创建第一l3-group的sub-nodes的gw/acc vrouters与第二l3-group的sub-nodes的gw/acc vrouters间的vlinks(vports)。\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer3AndExternalLayer2Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ // TODO: l3-group - ext-group<l2>: 为ext-group<l2>创建gw vrouter(vport),创建新vrouter与l3-group的sub-nodes的gw/acc vrouters间的vlinks(vports)。\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenLayer3AndExternalLayer3Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ // TODO: l3-group - ext-group<l3>: 创建ext-group<l3>的acc vrouter与l3-group的sub-nodes的gw/acc vrouters间的vlinks(vports)。\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenExternalLayer2Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ boolean sameIpPrefix;\r
+\r
+ sameIpPrefix = true;// TODO: for sameIpPrefix.\r
+\r
+ if ( sameIpPrefix ) {\r
+ if ( resolvingEndNode1 ) {\r
+ nodeMapper.resolveExternalLayer2Group(user, endNode1, virtualNetwork, userIntentVnMapping, false);\r
+ }\r
+\r
+ if ( resolvingEndNode2 ) {\r
+ nodeMapper.resolveExternalLayer2Group(user, endNode2, virtualNetwork, userIntentVnMapping, false);\r
+ }\r
+ } else {\r
+ if ( resolvingEndNode1 ) {\r
+ nodeMapper.resolveExternalLayer2Group(user, endNode1, virtualNetwork, userIntentVnMapping, true);\r
+ }\r
+\r
+ if ( resolvingEndNode2 ) {\r
+ nodeMapper.resolveExternalLayer2Group(user, endNode2, virtualNetwork, userIntentVnMapping, true);\r
+ }\r
+ }\r
+\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ IntentVnMappingResult intentVnMappingResult1 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult1 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult2 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult2 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(intentVnMappingResult1.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(intentVnMappingResult2.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property property = IntentResolverUtils\r
+ .getConnectionProperty(connection.getProperty(), new PropertyName("bandwidth"));\r
+ long bandwidth = 0;\r
+\r
+ if ( null != property ) {\r
+ bandwidth = /*1024 * */property.getPropertyValues().getIntValue().get(0).getValue();\r
+ }\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter1.getVirtualPort().add(virtualPort1);\r
+\r
+ VirtualPort virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter2.getVirtualPort().add(virtualPort2);\r
+\r
+ VirtualLink virtualLink1 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter2.getNodeId())\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ VirtualLink virtualLink2 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter2.getNodeId())\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualRouter1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+\r
+ if ( tempConnection ) {\r
+ List<VirtualLink> virtualLinks = new ArrayList<VirtualLink>(2);\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ return virtualLinks;\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(2);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(connection.getConnectionId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Connection)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenExternalLayer2AndLayer3Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ if ( resolvingEndNode1 ) {\r
+ nodeMapper.resolveExternalLayer2Group(user, endNode1, virtualNetwork, userIntentVnMapping, true);\r
+ }\r
+\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ IntentVnMappingResult intentVnMappingResult1 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult1 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult2 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult2 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(intentVnMappingResult1.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(intentVnMappingResult2.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property property = IntentResolverUtils\r
+ .getConnectionProperty(connection.getProperty(), new PropertyName("bandwidth"));\r
+ long bandwidth = 0;\r
+\r
+ if ( null != property ) {\r
+ bandwidth = /*1024 * */property.getPropertyValues().getIntValue().get(0).getValue();\r
+ }\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter1.getVirtualPort().add(virtualPort1);\r
+\r
+ VirtualPort virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter2.getVirtualPort().add(virtualPort2);\r
+\r
+ VirtualLink virtualLink1 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter2.getNodeId())\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ VirtualLink virtualLink2 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter2.getNodeId())\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualRouter1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+\r
+ if ( tempConnection ) {\r
+ List<VirtualLink> virtualLinks = new ArrayList<VirtualLink>(2);\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ return virtualLinks;\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(2);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(connection.getConnectionId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Connection)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param connection TODO\r
+ * @param endNode1 TODO\r
+ * @param endNode2 TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param tempConnection TODO\r
+ * @param resolvingEndNode1 TODO\r
+ * @param resolvingEndNode2 TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualLink> resolveP2PConnectionBetweenExternalLayer3Groups(User user,\r
+ Connection connection,\r
+ Node endNode1,\r
+ Node endNode2,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean tempConnection,\r
+ boolean resolvingEndNode1,\r
+ boolean resolvingEndNode2)\r
+ throws IntentResolutionException {\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ IntentVnMappingResult intentVnMappingResult1 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult1 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult2 = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(endNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult2 ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(intentVnMappingResult1.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(intentVnMappingResult2.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualRouter2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualRouter2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + endNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property property = IntentResolverUtils\r
+ .getConnectionProperty(connection.getProperty(), new PropertyName("bandwidth"));\r
+ long bandwidth = 0;\r
+\r
+ if ( null != property ) {\r
+ bandwidth = /*1024 * */property.getPropertyValues().getIntValue().get(0).getValue();\r
+ }\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter1.getVirtualPort().add(virtualPort1);\r
+\r
+ VirtualPort virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ virtualRouter2.getVirtualPort().add(virtualPort2);\r
+\r
+ VirtualLink virtualLink1 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter2.getNodeId())\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+ VirtualLink virtualLink2 = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter2.getNodeId())\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualRouter1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(bandwidth)\r
+ .build();\r
+\r
+ if ( tempConnection ) {\r
+ List<VirtualLink> virtualLinks = new ArrayList<VirtualLink>(2);\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ return virtualLinks;\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+\r
+ virtualLinks.add(virtualLink1);\r
+ virtualLinks.add(virtualLink2);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(2);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(connection.getConnectionId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Connection)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * Maintain the information of the user's flows. For example, query\r
+ * the values of the properties of the flow, such as the path of the\r
+ * flow, and store them into the data store.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class FlowManager {\r
+ private static final Logger LOG = LoggerFactory.getLogger(FlowManager.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ public FlowManager(DataBroker dataBroker) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+\r
+ LOG.debug("Initialized the renderer common flow manager.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Query the values of the properties of the flow, which are read-only\r
+ * for the user, and store them into the data store.\r
+ *\r
+ * @param userId The user id for the flow.\r
+ * @param flow The flow to be resolved.\r
+ */\r
+ protected void resolveFlow(UserId userId, Flow flow) throws IntentResolutionException {\r
+ // TODO\r
+\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+/**\r
+ * An exception in resolving the user intent.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class IntentResolutionException extends Exception {\r
+ private static final long serialVersionUID = -6843701204012305270L;\r
+\r
+ public IntentResolutionException() {\r
+ super();\r
+\r
+ return;\r
+ }\r
+\r
+ public IntentResolutionException(String message) {\r
+ super(message);\r
+\r
+ return;\r
+ }\r
+\r
+ public IntentResolutionException(Throwable cause) {\r
+ super(cause);\r
+\r
+ return;\r
+ }\r
+\r
+ public IntentResolutionException(String message, Throwable cause) {\r
+ super(message, cause);\r
+\r
+ return;\r
+ }\r
+\r
+ public IntentResolutionException(String message, Throwable cause,\r
+ boolean enableSuppression,\r
+ boolean writableStackTrace) {\r
+ super(message, cause, enableSuppression, writableStackTrace);\r
+\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+import com.google.common.base.Optional;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.nemo.intent.computation.PNComputationUnit;\r
+import org.opendaylight.nemo.intent.computation.VNComputationUnit;\r
+import org.opendaylight.nemo.intent.computation.VNMappingUnit;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalPaths;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPathKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.VirtualNetworks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArp;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.routes.VirtualRoute;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.IntentVnMappingResults;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.VnPnMappingResults;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMappingBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMappingKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.user.vn.pn.mapping.VnPnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalPathId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNetworkId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.HashMap;\r
+import java.util.LinkedList;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+/**\r
+ * Provide the user intent resolution APIs and distribute the user intents\r
+ * to corresponding handling classes.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class IntentResolver implements AutoCloseable {\r
+ private static final Logger LOG = LoggerFactory.getLogger(IntentResolver.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ /**\r
+ * The node mapper to resolve the user's node intent.\r
+ */\r
+ private NodeMapper nodeMapper;\r
+\r
+ /**\r
+ * The connection mapper to resolve the user's connection intent.\r
+ */\r
+ private ConnectionMapper connectionMapper;\r
+\r
+ /**\r
+ * The flow manager to resolve the user's flow intent.\r
+ */\r
+ private FlowManager flowManager;\r
+\r
+ /**\r
+ * The operation resolver to resolve the user's operation intent.\r
+ */\r
+ private OperationResolver operationResolver;\r
+\r
+ /**\r
+ * The physical network computation unit.\r
+ */\r
+ private PNComputationUnit pnComputationUnit;\r
+\r
+ /**\r
+ * The virtual network computation unit for all users.\r
+ */\r
+ private Map<UserId, VNComputationUnit> vnComputationUnits;\r
+\r
+ /**\r
+ * The virtual network mapping unit.\r
+ */\r
+ private VNMappingUnit vnMappingUnit;\r
+\r
+ public IntentResolver(DataBroker dataBroker) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+\r
+ nodeMapper = new NodeMapper(dataBroker);\r
+ connectionMapper = new ConnectionMapper(dataBroker, nodeMapper);\r
+ flowManager = new FlowManager(dataBroker);\r
+ operationResolver = new OperationResolver(dataBroker);\r
+\r
+ pnComputationUnit = new PNComputationUnit(dataBroker);\r
+ vnComputationUnits = new HashMap<UserId, VNComputationUnit>();\r
+ vnMappingUnit = new VNMappingUnit(dataBroker, pnComputationUnit);\r
+\r
+ LOG.debug("Initialized the renderer common intent resolver.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Resolve the user's intents to generate the virtual network, then map\r
+ * the virtual network into the underlying physical network, finally, store\r
+ * the generated intent mapping results into the data store, and various\r
+ * renderers configure the underlying networks according to these results.\r
+ *\r
+ * @param userId The user id for the intents to be resolved.\r
+ */\r
+ public void resolveIntent(UserId userId) throws Exception {\r
+ VNComputationUnit vnComputationUnit = vnComputationUnits.get(userId);\r
+\r
+ VirtualNetworkId virtualNetworkId = new VirtualNetworkId(userId.getValue());\r
+ VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(virtualNetworkId);\r
+\r
+ InstanceIdentifier<VirtualNetwork> virtualNetworkIid = InstanceIdentifier\r
+ .builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .build();\r
+ InstanceIdentifier<UserIntentVnMapping> userIntentVnMappingIid = InstanceIdentifier\r
+ .builder(IntentVnMappingResults.class)\r
+ .child(UserIntentVnMapping.class, new UserIntentVnMappingKey(userId))\r
+ .build();\r
+ InstanceIdentifier<UserVnPnMapping> userVnPnMappingIid = InstanceIdentifier\r
+ .builder(VnPnMappingResults.class)\r
+ .child(UserVnPnMapping.class, new UserVnPnMappingKey(virtualNetworkId))\r
+ .build();\r
+\r
+ if ( null != vnComputationUnit ) {\r
+ vnComputationUnit.close();\r
+ vnComputationUnits.remove(userId);\r
+\r
+ ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();\r
+\r
+ Optional<UserVnPnMapping> result;\r
+\r
+ try {\r
+ result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new IntentResolutionException("Can not read the vn-pn mapping results for the user " +\r
+ userId.getValue() + ".");\r
+ }\r
+\r
+ if ( result.isPresent() ) {\r
+ UserVnPnMapping userVnPnMapping = result.get();\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+ InstanceIdentifier<PhysicalPath> physicalPathIid;\r
+ PhysicalPathId physicalPathId;\r
+\r
+ for ( VnPnMappingResult vnPnMappingResult : vnPnMappingResults ) {\r
+ if ( VnPnMappingResult.VirtualResourceType.Vlink == vnPnMappingResult.getVirtualResourceType() ) {\r
+ physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPathIid = InstanceIdentifier.builder(PhysicalNetwork.class)\r
+ .child(PhysicalPaths.class)\r
+ .child(PhysicalPath.class, new PhysicalPathKey(physicalPathId))\r
+ .build();\r
+\r
+ readWriteTransaction.delete(LogicalDatastoreType.OPERATIONAL, physicalPathIid);\r
+ }\r
+ }\r
+ }\r
+\r
+// readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid);\r
+// readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid);\r
+// readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid);\r
+ // TODO: 删除intent processing status\r
+\r
+ readWriteTransaction.submit();\r
+ }\r
+\r
+ ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();\r
+\r
+ InstanceIdentifier<User> userIid = InstanceIdentifier.builder(Users.class)\r
+ .child(User.class, new UserKey(userId))\r
+ .build();\r
+ Optional<User> result;\r
+\r
+ try {\r
+ result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, userIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new IntentResolutionException("Can not read the data of the user " +\r
+ userId.getValue() + ".");\r
+ }\r
+\r
+ if ( !result.isPresent() ) {\r
+ throw new IntentResolutionException("The data of the user " +\r
+ userId.getValue() + " does not exist.");\r
+ }\r
+\r
+ User user = result.get();\r
+\r
+ if ( null != user.getObjects() ) {\r
+ VirtualNodes virtualNodes = new VirtualNodesBuilder()\r
+ .setVirtualNode(new LinkedList<VirtualNode>())\r
+ .build();\r
+ VirtualLinks virtualLinks = new VirtualLinksBuilder()\r
+ .setVirtualLink(new LinkedList<VirtualLink>())\r
+ .build();\r
+ VirtualPaths virtualPaths = new VirtualPathsBuilder()\r
+ .setVirtualPath(new LinkedList<VirtualPath>())\r
+ .build();\r
+ VirtualRoutes virtualRoutes = new VirtualRoutesBuilder()\r
+ .setVirtualRoute(new LinkedList<VirtualRoute>())\r
+ .build();\r
+ VirtualArps virtualArps = new VirtualArpsBuilder()\r
+ .setVirtualArp(new LinkedList<VirtualArp>())\r
+ .build();\r
+ VirtualNetwork virtualNetwork = new VirtualNetworkBuilder()\r
+ .setNetworkId(virtualNetworkId)\r
+ .setUserId(userId)\r
+ .setVirtualNodes(virtualNodes)\r
+ .setVirtualLinks(virtualLinks)\r
+ .setVirtualPaths(virtualPaths)\r
+ .setVirtualRoutes(virtualRoutes)\r
+ .setVirtualArps(virtualArps)\r
+ .build();\r
+\r
+ UserIntentVnMapping userIntentVnMapping = new UserIntentVnMappingBuilder()\r
+ .setUserId(userId)\r
+ .setVirtualNetworkId(virtualNetworkId)\r
+ .setIntentVnMappingResult(new LinkedList<IntentVnMappingResult>())\r
+ .build();\r
+\r
+ UserVnPnMapping userVnPnMapping = new UserVnPnMappingBuilder()\r
+ .setVirtualNetworkId(virtualNetworkId)\r
+ .setUserId(userId)\r
+ .setVnPnMappingResult(new LinkedList<VnPnMappingResult>())\r
+ .build();\r
+\r
+ List<PhysicalPath> physicalPaths = new LinkedList<PhysicalPath>();\r
+\r
+ List<Node> nodes = user.getObjects().getNode();\r
+ List<Node> hosts = new LinkedList<Node>();\r
+ List<Node> layer2Groups = new LinkedList<Node>();\r
+ List<Node> layer3Groups = new LinkedList<Node>();\r
+ List<Node> externalLayer3Groups = new LinkedList<Node>();\r
+ List<Node> serviceChainGroups = new LinkedList<Node>();\r
+ List<Node> serviceFunctions = new LinkedList<Node>();\r
+\r
+ NodeType hostNodeType = new NodeType("host");\r
+ NodeType layer2GroupNodeType = new NodeType("l2-group");\r
+ NodeType layer3GroupNodeType = new NodeType("l3-group");\r
+ NodeType externalGroupNodeType = new NodeType("ext-group");\r
+ NodeType serviceChainGroupNodeType = new NodeType("chain-group");\r
+ NodeType firewallNodeType = new NodeType("fw");\r
+ NodeType loadbalancerNodeType = new NodeType("lb");\r
+ NodeType cacheNodeType = new NodeType("cache");\r
+ NodeType nodeType;\r
+\r
+ if ( null != nodes ) {\r
+ for ( Node node : nodes ) {\r
+ nodeType = node.getNodeType();\r
+\r
+ if ( nodeType.equals(hostNodeType) ) {\r
+ hosts.add(node);\r
+ }\r
+\r
+ if ( nodeType.equals(layer2GroupNodeType) ) {\r
+ layer2Groups.add(node);\r
+ }\r
+\r
+ if ( nodeType.equals(layer3GroupNodeType) ) {\r
+ layer3Groups.add(node);\r
+ }\r
+\r
+ if ( nodeType.equals(externalGroupNodeType) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(node) ) {\r
+ externalLayer3Groups.add(node);\r
+ }\r
+ }\r
+\r
+ if ( nodeType.equals(serviceChainGroupNodeType) ) {\r
+ serviceChainGroups.add(node);\r
+ }\r
+\r
+ if ( nodeType.equals(firewallNodeType)\r
+ || nodeType.equals(loadbalancerNodeType)\r
+ || nodeType.equals(cacheNodeType) ) {\r
+ serviceFunctions.add(node);\r
+ }\r
+ }\r
+\r
+ for ( Node node : hosts ) {\r
+ nodeMapper.resolveHost(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+\r
+ for ( Node node : layer2Groups ) {\r
+ nodeMapper.resolveLayer2Group(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+\r
+ for ( Node node : externalLayer3Groups ) {\r
+ nodeMapper.resolveExternalLayer3Group(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+\r
+ for ( Node node : layer3Groups ) {\r
+ nodeMapper.resolveLayer3Group(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+\r
+ for ( Node node : serviceFunctions ) {\r
+ nodeMapper.resolveServiceFunction(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+\r
+ for ( Node node : serviceChainGroups ) {\r
+ nodeMapper.resolveServiceChainGroup(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+ }\r
+\r
+ List<Connection> connections = user.getObjects().getConnection();\r
+\r
+ if ( null != connections ) {\r
+ for ( Connection connection : connections ) {\r
+ connectionMapper.resolveConnection(user, connection, virtualNetwork, userIntentVnMapping);\r
+ }\r
+ }\r
+\r
+ List<Flow> flows = user.getObjects().getFlow();\r
+\r
+ if ( null != flows ) {\r
+ for ( Flow flow : flows ) {\r
+ flowManager.resolveFlow(userId, flow);\r
+ }\r
+ }\r
+\r
+ if ( null != user.getOperations() ) {\r
+ List<Operation> operations = user.getOperations().getOperation();\r
+\r
+ if ( null != operations ) {\r
+ for ( Operation operation : operations ) {\r
+ operationResolver.resolveOperation(user, operation, virtualNetwork, userIntentVnMapping);\r
+ }\r
+ }\r
+ }\r
+\r
+ vnMappingUnit.virtualNetworkMapping(virtualNetwork, userVnPnMapping, physicalPaths);\r
+ vnComputationUnit = new VNComputationUnit(dataBroker, virtualNetwork);\r
+ vnComputationUnits.put(userId, vnComputationUnit);\r
+\r
+ // for testing - jizhigang\r
+ System.out.println(virtualNetwork);\r
+ System.out.println(userIntentVnMapping);\r
+ System.out.println(userVnPnMapping);\r
+ System.out.println(physicalPaths);\r
+ // for testing - jizhigang\r
+\r
+ readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid, virtualNetwork, true);\r
+ readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid, userIntentVnMapping, true);\r
+ readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid, userVnPnMapping, true);\r
+\r
+ InstanceIdentifier<PhysicalPath> physicalPathIid;\r
+\r
+ for ( PhysicalPath physicalPath : physicalPaths ) {\r
+ physicalPathIid = InstanceIdentifier.builder(PhysicalNetwork.class)\r
+ .child(PhysicalPaths.class)\r
+ .child(PhysicalPath.class, new PhysicalPathKey(physicalPath.getPathId()))\r
+ .build();\r
+\r
+ readWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, physicalPathIid, physicalPath, true);\r
+ }\r
+\r
+ readWriteTransaction.submit();\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+ if ( null != pnComputationUnit ) {\r
+ pnComputationUnit.close();\r
+ }\r
+\r
+ for ( VNComputationUnit vnComputationUnit : vnComputationUnits.values() ) {\r
+ if ( null != vnComputationUnit ) {\r
+ vnComputationUnit.close();\r
+ }\r
+ }\r
+\r
+ if ( null != vnMappingUnit ) {\r
+ vnMappingUnit.close();\r
+ }\r
+\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHost;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResource;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalHostId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalNodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.flow.instance.MatchItem;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.Property;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.SubNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.instance.property.values.StringValue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.operation.instance.Action;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * Implement the common utilities frequently used in\r
+ * the intent resolution.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class IntentResolverUtils {\r
+ /**\r
+ * Check whether the node is an external layer2 group or layer3 group.\r
+ *\r
+ * @param node The node to be checked.\r
+ * @return True if the node is an external layer3 group.\r
+ */\r
+ protected static boolean checkExternalLayer3Group(Node node) {\r
+ PropertyName propertyName = new PropertyName("ac-info-network");\r
+ Property property = getNodeProperty(node.getProperty(), propertyName);\r
+\r
+ if ( null != property ) {\r
+ String propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
+\r
+ if ( propertyValue.equals("layer3") ) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param physicalHosts TODO\r
+ * @param node TODO\r
+ * @return TODO\r
+ */\r
+ protected static PhysicalHost getPhysicalHost(List<PhysicalHost> physicalHosts, Node node) {\r
+ PhysicalHostId physicalHostId = new PhysicalHostId(node.getNodeId().getValue());\r
+\r
+ return getPhysicalHost(physicalHosts, physicalHostId);\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param properties TODO\r
+ * @param propertyName TODO\r
+ * @return TODO\r
+ */\r
+ protected static Property getNodeProperty(List<Property> properties, PropertyName propertyName) {\r
+ if ( null != properties ) {\r
+ for ( Property property : properties ) {\r
+ if ( property.getPropertyName().equals(propertyName) ) {\r
+ return property;\r
+ }\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param property TODO\r
+ * @return TODO\r
+ */\r
+ protected static PhysicalNodeId generatePhysicalNodeIdFromNodeLocationProperty(Property property) {\r
+ String propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
+\r
+ return new PhysicalNodeId(propertyValue.substring(0, propertyValue.lastIndexOf(':')));\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param intentVnMappingResults TODO\r
+ * @param intentId TODO\r
+ * @return TODO\r
+ */\r
+ protected static IntentVnMappingResult getIntentVnMappingResult(\r
+ List<IntentVnMappingResult> intentVnMappingResults, IntentId intentId) {\r
+ for ( IntentVnMappingResult intentVnMappingResult : intentVnMappingResults ) {\r
+ if ( intentVnMappingResult.getIntentId().equals(intentId) ) {\r
+ return intentVnMappingResult;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNodes TODO\r
+ * @param virtualNodeId TODO\r
+ * @return TODO\r
+ */\r
+ protected static VirtualNode getVirtualNode(List<VirtualNode> virtualNodes,\r
+ VirtualNodeId virtualNodeId) {\r
+ for ( VirtualNode virtualNode : virtualNodes ) {\r
+ if ( virtualNode.getNodeId().equals(virtualNodeId) ) {\r
+ return virtualNode;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param nodes TODO\r
+ * @param nodeId TODO\r
+ * @return TODO\r
+ */\r
+ protected static Node getNode(List<Node> nodes, NodeId nodeId) {\r
+ for ( Node node : nodes ) {\r
+ if ( node.getNodeId().equals(nodeId) ) {\r
+ return node;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param properties TODO\r
+ * @param propertyName TODO\r
+ * @return TODO\r
+ */\r
+ protected static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property getConnectionProperty(\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property> properties,\r
+ PropertyName propertyName) {\r
+ if ( null != properties ) {\r
+ for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property\r
+ property : properties ) {\r
+ if ( property.getPropertyName().equals(propertyName) ) {\r
+ return property;\r
+ }\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param subNodes TODO\r
+ * @return TODO\r
+ */\r
+ protected static List<SubNode> sortSubNodes(List<SubNode> subNodes) {\r
+ if ( subNodes.isEmpty() || 1 == subNodes.size() ) {\r
+ return subNodes;\r
+ }\r
+\r
+ List<SubNode> sortedSubNodes = new ArrayList<SubNode>(subNodes.size());\r
+ sortedSubNodes.addAll(subNodes);\r
+\r
+ for ( SubNode subNode : subNodes ) {\r
+ sortedSubNodes.set(subNode.getOrder().intValue(), subNode);\r
+ }\r
+\r
+ return sortedSubNodes;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param subNodes TODO\r
+ * @param nodes TODO\r
+ * @return TODO\r
+ */\r
+ protected static boolean checkAllLayer2OperatingMode(List<SubNode> subNodes, List<Node> nodes) {\r
+ if ( subNodes.isEmpty() ) {\r
+ return false;\r
+ }\r
+\r
+ Node node;\r
+ PropertyName propertyName = new PropertyName("operating-mode");\r
+ Property property;\r
+ String propertyValue;\r
+\r
+ for ( SubNode subNode : subNodes ) {\r
+ node = getNode(nodes, subNode.getNodeId());\r
+\r
+ if ( null == node ) {\r
+ return false;\r
+ }\r
+\r
+ property = getNodeProperty(node.getProperty(), propertyName);\r
+\r
+ if ( null == property ) {\r
+ return false;\r
+ }\r
+\r
+ propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
+\r
+ if ( !propertyValue.equals("layer2") ) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param subNodes TODO\r
+ * @param nodes TODO\r
+ * @return TODO\r
+ */\r
+ protected static boolean checkAllLayer3OperatingMode(List<SubNode> subNodes, List<Node> nodes) {\r
+ if ( subNodes.isEmpty() ) {\r
+ return false;\r
+ }\r
+\r
+ Node node;\r
+ PropertyName propertyName = new PropertyName("operating-mode");\r
+ Property property;\r
+ String propertyValue;\r
+\r
+ for ( SubNode subNode : subNodes ) {\r
+ node = getNode(nodes, subNode.getNodeId());\r
+\r
+ if ( null == node ) {\r
+ return false;\r
+ }\r
+\r
+ property = getNodeProperty(node.getProperty(), propertyName);\r
+\r
+ if ( null == property ) {\r
+ return false;\r
+ }\r
+\r
+ propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
+\r
+ if ( !propertyValue.equals("layer3") ) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualLinks TODO\r
+ * @param srcVirtualNodeId TODO\r
+ * @param destVirtualNodeId TODO\r
+ * @return TODO\r
+ */\r
+ protected static VirtualLink getVirtualLink(List<VirtualLink> virtualLinks,\r
+ VirtualNodeId srcVirtualNodeId,\r
+ VirtualNodeId destVirtualNodeId) {\r
+ for ( VirtualLink virtualLink : virtualLinks ) {\r
+ if ( virtualLink.getSrcNodeId().equals(srcVirtualNodeId)\r
+ && virtualLink.getDestNodeId().equals(destVirtualNodeId) ) {\r
+ return virtualLink;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param objects TODO\r
+ * @param objectId TODO\r
+ * @return TODO\r
+ */\r
+ protected static DataObject getObject(Objects objects, ObjectId objectId) {\r
+ List<Node> nodes = objects.getNode();\r
+\r
+ if ( null != nodes ) {\r
+ NodeId nodeId = new NodeId(objectId.getValue());\r
+ Node node = getNode(nodes, nodeId);\r
+\r
+ if ( null != node ) {\r
+ return node;\r
+ }\r
+ }\r
+\r
+ List<Connection> connections = objects.getConnection();\r
+\r
+ if ( null != connections ) {\r
+ ConnectionId connectionId = new ConnectionId(objectId.getValue());\r
+ Connection connection = getConnection(connections, connectionId);\r
+\r
+ if ( null != connection ) {\r
+ return connection;\r
+ }\r
+ }\r
+\r
+ List<Flow> flows = objects.getFlow();\r
+\r
+ if ( null != flows ) {\r
+ FlowId flowId = new FlowId(objectId.getValue());\r
+ Flow flow = getFlow(flows, flowId);\r
+\r
+ if ( null != flow ) {\r
+ return flow;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param operations TODO\r
+ * @param operation TODO\r
+ * @return TODO\r
+ */\r
+ protected static List<Operation> getSameTargetObjectOperations(List<Operation> operations,\r
+ Operation operation) {\r
+ // TODO\r
+\r
+ return new ArrayList<Operation>(0);\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param operations TODO\r
+ * @param operation TODO\r
+ * @param greaterPriorityOperations TODO\r
+ * @param equalPriorityOperations TODO\r
+ */\r
+ protected static void getGreaterAndEqualPriorityOperations(List<Operation> operations, Operation operation,\r
+ List<Operation> greaterPriorityOperations,\r
+ List<Operation> equalPriorityOperations) {\r
+ // TODO\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param operations TODO\r
+ * @param operation TODO\r
+ * @return TODO\r
+ */\r
+ protected static Operation getConflictingOperation(List<Operation> operations,\r
+ Operation operation) {\r
+ // TODO\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param operations TODO\r
+ * @param operation TODO\r
+ * @return TODO\r
+ */\r
+ protected static List<Operation> getConflictingOperations(List<Operation> operations,\r
+ Operation operation) {\r
+ // TODO\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param actions TODO\r
+ * @param actionName TODO\r
+ * @return TODO\r
+ */\r
+ protected static Action getAction(List<Action> actions, ActionName actionName) {\r
+ for ( Action action : actions ) {\r
+ if ( action.getActionName().equals(actionName) ) {\r
+ return action;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNodes TODO\r
+ * @param flow TODO\r
+ * @param nodes TODO\r
+ * @param intentVnMappingResults TODO\r
+ * @return TODO\r
+ */\r
+ protected static VirtualNode getSourceVirtualRouterOfFlow(List<VirtualNode> virtualNodes,\r
+ Flow flow, List<Node> nodes,\r
+ List<IntentVnMappingResult> intentVnMappingResults) {\r
+ MatchItemName matchItemName = new MatchItemName("src-ip");\r
+ MatchItem matchItem = getMatchItem(flow.getMatchItem(), matchItemName);\r
+\r
+ if ( null == matchItem ) {\r
+ return null;\r
+ }\r
+\r
+ String matchItemValue = matchItem.getMatchItemValue().getStringValue();\r
+ VirtualNode virtualNode = getVirtualRouterWithIpPrefix(virtualNodes,\r
+ matchItemValue, nodes, intentVnMappingResults);\r
+\r
+ return virtualNode;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNodes TODO\r
+ * @param flow TODO\r
+ * @param nodes TODO\r
+ * @param intentVnMappingResults TODO\r
+ * @return TODO\r
+ */\r
+ protected static VirtualNode getDestinationVirtualRouterOfFlow(List<VirtualNode> virtualNodes,\r
+ Flow flow, List<Node> nodes,\r
+ List<IntentVnMappingResult> intentVnMappingResults) {\r
+ MatchItemName matchItemName = new MatchItemName("dst-ip");\r
+ MatchItem matchItem = getMatchItem(flow.getMatchItem(), matchItemName);\r
+\r
+ if ( null == matchItem ) {\r
+ return null;\r
+ }\r
+\r
+ String matchItemValue = matchItem.getMatchItemValue().getStringValue();\r
+ VirtualNode virtualNode = getVirtualRouterWithIpPrefix(virtualNodes,\r
+ matchItemValue, nodes, intentVnMappingResults);\r
+\r
+ return virtualNode;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualResources TODO\r
+ * @return TODO\r
+ */\r
+ protected static List<VirtualResource> sortVirtualResources(List<VirtualResource> virtualResources) {\r
+ if ( virtualResources.isEmpty() || 1 == virtualResources.size() ) {\r
+ return virtualResources;\r
+ }\r
+\r
+ List<VirtualResource> sortedVirtualResources = new ArrayList<VirtualResource>(virtualResources.size());\r
+ sortedVirtualResources.addAll(virtualResources);\r
+\r
+ for ( VirtualResource virtualResource : virtualResources ) {\r
+ sortedVirtualResources.set(virtualResource.getOrder().intValue(), virtualResource);\r
+ }\r
+\r
+ return sortedVirtualResources;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param physicalHosts TODO\r
+ * @param physicalHostId TODO\r
+ * @return TODO\r
+ */\r
+ private static PhysicalHost getPhysicalHost(List<PhysicalHost> physicalHosts,\r
+ PhysicalHostId physicalHostId) {\r
+ for ( PhysicalHost physicalHost : physicalHosts ) {\r
+ if ( physicalHost.getHostId().equals(physicalHostId) ) {\r
+ return physicalHost;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param connections TODO\r
+ * @param connectionId TODO\r
+ * @return TODO\r
+ */\r
+ private static Connection getConnection(List<Connection> connections, ConnectionId connectionId) {\r
+ for ( Connection connection : connections ) {\r
+ if ( connection.getConnectionId().equals(connectionId) ) {\r
+ return connection;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param flows TODO\r
+ * @param flowId TODO\r
+ * @return TODO\r
+ */\r
+ private static Flow getFlow(List<Flow> flows, FlowId flowId) {\r
+ for ( Flow flow : flows ) {\r
+ if ( flow.getFlowId().equals(flowId) ) {\r
+ return flow;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param matchItems TODO\r
+ * @param matchItemName TODO\r
+ * @return TODO\r
+ */\r
+ private static MatchItem getMatchItem(List<MatchItem> matchItems, MatchItemName matchItemName) {\r
+ if ( null != matchItems ) {\r
+ for ( MatchItem matchItem : matchItems ) {\r
+ if ( matchItem.getMatchItemName().equals(matchItemName) ) {\r
+ return matchItem;\r
+ }\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNodes TODO\r
+ * @param ipPrefix TODO\r
+ * @param nodes TODO\r
+ * @param intentVnMappingResults TODO\r
+ * @return TODO\r
+ */\r
+ private static VirtualNode getVirtualRouterWithIpPrefix(List<VirtualNode> virtualNodes,\r
+ String ipPrefix, List<Node> nodes,\r
+ List<IntentVnMappingResult> intentVnMappingResults) {\r
+ NodeType layer2GroupNodeType = new NodeType("l2-group");\r
+ NodeType externalGroupNodeType = new NodeType("ext-group");\r
+ PropertyName propertyName = new PropertyName("ip-prefix");\r
+ Property property;\r
+ List<StringValue> propertyValues;\r
+ IntentVnMappingResult intentVnMappingResult;\r
+ VirtualResource virtualResource;\r
+ VirtualNodeId virtualNodeId;\r
+ VirtualNode virtualNode;\r
+\r
+ for ( Node node : nodes ) {\r
+ if ( node.getNodeType().equals(layer2GroupNodeType)\r
+ || node.getNodeType().equals(externalGroupNodeType) ) {\r
+ property = getNodeProperty(node.getProperty(), propertyName);\r
+\r
+ if ( null != property ) {\r
+ propertyValues = property.getPropertyValues().getStringValue();\r
+\r
+ if ( containPropertyValue(propertyValues, ipPrefix) ) {\r
+ intentVnMappingResult = getIntentVnMappingResult(intentVnMappingResults,\r
+ new IntentId(node.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult ) {\r
+ return null;\r
+ }\r
+\r
+ virtualResource = intentVnMappingResult.getVirtualResource().get(0);\r
+\r
+ if ( VirtualResource.VirtualResourceType.Vport\r
+ == virtualResource.getVirtualResourceType() ) {\r
+ virtualNodeId = new VirtualNodeId(\r
+ virtualResource.getParentVirtualResourceEntityId().getValue());\r
+ } else if ( VirtualResource.VirtualResourceType.Vnode\r
+ == virtualResource.getVirtualResourceType() ) {\r
+ virtualNodeId = new VirtualNodeId(\r
+ virtualResource.getVirtualResourceEntityId().getValue());\r
+ } else {\r
+ return null;\r
+ }\r
+\r
+ virtualNode = getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualNode ) {\r
+ return null;\r
+ }\r
+\r
+ if ( VirtualNode.NodeType.Vrouter == virtualNode.getNodeType() ) {\r
+ return virtualNode;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param propertyValues TODO\r
+ * @param propertyValue TODO\r
+ * @return TODO\r
+ */\r
+ private static boolean containPropertyValue(List<StringValue> propertyValues, String propertyValue) {\r
+ for ( StringValue stringValue : propertyValues ) {\r
+ if ( stringValue.getValue().equals(propertyValue) ) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+import com.google.common.base.Optional;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.AttributeValue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.AttributeValueBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalHosts;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHost;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArp;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArpBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLinkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNodeBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPathBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.port.instance.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.port.instance.PhysicalResourceRequirement;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.port.instance.PhysicalResourceRequirementBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResultBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResource;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResourceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.IntentId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.PropertyName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.Property;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.SubNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.instance.property.values.StringValue;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.*;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+/**\r
+ * Resolve the user's node intent. Create the virtual node according to\r
+ * the intent if it's needed, and then map the created virtual node into\r
+ * the physical network. Finally, store these intent mapping results\r
+ * into the data store.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class NodeMapper {\r
+ private static final Logger LOG = LoggerFactory.getLogger(NodeMapper.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ public NodeMapper(DataBroker dataBroker) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+\r
+ LOG.debug("Initialized the renderer common node mapper.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Resolve the user's node intent, perform the necessary intent\r
+ * mapping, and store the intent mapping results into the data store.\r
+ *\r
+ * @param user The user for the node.\r
+ * @param node The node to be resolved.\r
+ * @param virtualNetwork The virtual network for the user.\r
+ * @param userIntentVnMapping The intent-vn mapping for the user.\r
+ */\r
+ protected void resolveNode(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ NodeType nodeType = node.getNodeType();\r
+\r
+ if ( nodeType.equals(new NodeType("host")) ) {\r
+ resolveHost(user, node, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ if ( nodeType.equals(new NodeType(("l2-group"))) ) {\r
+ resolveLayer2Group(user, node, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ if ( nodeType.equals(new NodeType("l3-group")) ) {\r
+ resolveLayer3Group(user, node, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ if ( nodeType.equals(new NodeType("ext-group")) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(node) ) {\r
+ resolveExternalLayer3Group(user, node, virtualNetwork, userIntentVnMapping);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ if ( nodeType.equals(new NodeType("chain-group")) ) {\r
+ resolveServiceChainGroup(user, node, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ if ( nodeType.equals(new NodeType("fw"))\r
+ || nodeType.equals(new NodeType("lb"))\r
+ || nodeType.equals(new NodeType("cache")) ) {\r
+ resolveServiceFunction(user, node, virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ throw new IntentResolutionException("Unknown node type.");\r
+\r
+// return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveHost(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();\r
+\r
+ InstanceIdentifier<PhysicalHosts> physicalHostsIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalHosts.class)\r
+ .build();\r
+ Optional<PhysicalHosts> result;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, physicalHostsIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new IntentResolutionException("Can not read the physical hosts.");\r
+ }\r
+\r
+ if ( !result.isPresent() ) {\r
+ throw new IntentResolutionException("The physical hosts do not exist.");\r
+ }\r
+\r
+ PhysicalHosts physicalHosts = result.get();\r
+ List<PhysicalHost> physicalHostList = physicalHosts.getPhysicalHost();\r
+ PhysicalHost physicalHost = IntentResolverUtils.getPhysicalHost(physicalHostList, node);\r
+\r
+ if ( null == physicalHost ) {\r
+ throw new IntentResolutionException("The physical host corresponding to the node " +\r
+ node.getNodeId().getValue() + " does not exist.");\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement> physicalResourceRequirements =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue = new AttributeValueBuilder()\r
+ .setStringValue(physicalHost.getNodeId().getValue())\r
+ .build();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement physicalResourceRequirement =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue)\r
+ .setAttributeMatchPattern(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements.add(physicalResourceRequirement);\r
+\r
+ VirtualNode virtualNode = new VirtualNodeBuilder()\r
+ .setNodeId(new VirtualNodeId(UUID.randomUUID().toString()))\r
+ .setNodeType(VirtualNode.NodeType.Vswitch)\r
+ .setVirtualPort(new LinkedList<VirtualPort>())\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements)\r
+ .build();\r
+\r
+ virtualNetwork.getVirtualNodes().getVirtualNode().add(virtualNode);\r
+\r
+ List<MacAddress> macAddresses = new ArrayList<MacAddress>(1);\r
+ macAddresses.add(physicalHost.getMacAddress());\r
+ ExternalMacAddresses externalMacAddresses = new ExternalMacAddressesBuilder()\r
+ .setExternalMacAddress(macAddresses)\r
+ .build();\r
+\r
+ List<PhysicalResourceRequirement> physicalResourceRequirements1 =\r
+ new ArrayList<PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue1 = new AttributeValueBuilder()\r
+ .setStringValue(physicalHost.getPortId().getValue())\r
+ .build();\r
+ PhysicalResourceRequirement physicalResourceRequirement1 = new PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue1)\r
+ .setAttributeMatchPattern(PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements1.add(physicalResourceRequirement1);\r
+\r
+ VirtualPort virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.External)\r
+ .setExternalMacAddresses(externalMacAddresses)\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements1)\r
+ .build();\r
+\r
+ virtualNode.getVirtualPort().add(virtualPort);\r
+\r
+ List<VirtualArp> virtualArps = virtualNetwork.getVirtualArps().getVirtualArp();\r
+ VirtualArp virtualArp;\r
+\r
+ for ( IpAddress ipAddress : physicalHost.getIpAddresses().getIpAddress() ) {\r
+ virtualArp = new VirtualArpBuilder()\r
+ .setIpAddress(ipAddress)\r
+ .setMacAddress(physicalHost.getMacAddress())\r
+ .setNodeId(virtualNode.getNodeId())\r
+ .setPortId(virtualPort.getPortId())\r
+ .build();\r
+ virtualArps.add(virtualArp);\r
+ }\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(1);\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vport)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPort.getPortId().getValue()))\r
+ .setParentVirtualResourceEntityId(new VirtualResourceEntityId(virtualNode.getNodeId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(node.getNodeId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Node)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ userIntentVnMapping.getIntentVnMappingResult().add(intentVnMappingResult);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveLayer2Group(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ List<Node> nodes = user.getObjects().getNode();\r
+ List<SubNode> subNodes = node.getSubNode();\r
+ Node node1;\r
+ NodeType nodeType = new NodeType("ext-group");\r
+ List<VirtualNode> virtualSwitches = new ArrayList<VirtualNode>(subNodes.size());\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ IntentVnMappingResult intentVnMappingResult;\r
+ VirtualNode virtualNode;\r
+\r
+ for ( SubNode subNode : subNodes ) {\r
+ node1 = IntentResolverUtils.getNode(nodes, subNode.getNodeId());\r
+\r
+ if ( null == node1 ) {\r
+ throw new IntentResolutionException("The sub-node " + subNode.getNodeId().getValue() +\r
+ " of the node " + node.getNodeId().getValue() + " does not exist.");\r
+ }\r
+\r
+ if ( node1.getNodeType().equals(nodeType) ) {\r
+ if ( IntentResolverUtils.checkExternalLayer3Group(node1) ) {\r
+ throw new IntentResolutionException("The sub-node " + subNode.getNodeId().getValue() +\r
+ " of the node " + node.getNodeId().getValue() + " can't be layer3 group.");\r
+ }\r
+\r
+ resolveExternalLayer2Group(user, node1, virtualNetwork, userIntentVnMapping, false);\r
+ }\r
+\r
+ intentVnMappingResult = IntentResolverUtils.getIntentVnMappingResult(intentVnMappingResults,\r
+ new IntentId(node1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + node1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNode = IntentResolverUtils.getVirtualNode(virtualNodes,\r
+ new VirtualNodeId(intentVnMappingResult.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue()));\r
+\r
+ if ( null == virtualNode ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created for " +\r
+ "the node " + node1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualSwitches.add(virtualNode);\r
+ }\r
+\r
+ Property locationProperty = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("location"));\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement> physicalResourceRequirements;\r
+\r
+ if ( null == locationProperty ) {\r
+ physicalResourceRequirements =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>(0);\r
+ } else {\r
+ physicalResourceRequirements =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue = new AttributeValueBuilder()\r
+ .setStringValue(locationProperty.getPropertyValues().getStringValue().get(0).getValue())\r
+ .build();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement physicalResourceRequirement =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue)\r
+ .setAttributeMatchPattern(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements.add(physicalResourceRequirement);\r
+ }\r
+\r
+ VirtualNode virtualRouter = new VirtualNodeBuilder()\r
+ .setNodeId(new VirtualNodeId(UUID.randomUUID().toString()))\r
+ .setNodeType(VirtualNode.NodeType.Vrouter)\r
+ .setVirtualPort(new LinkedList<VirtualPort>())\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements)\r
+ .build();\r
+\r
+ virtualNodes.add(virtualRouter);\r
+\r
+ ExternalIpPrefixes externalIpPrefixes;\r
+ Property ipPrefixProperty = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("ip-prefix"));\r
+\r
+ if ( null == ipPrefixProperty ) {\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(new ArrayList<IpPrefix>(0))\r
+ .build();\r
+ } else {\r
+ List<IpPrefix> ipPrefixes = new ArrayList<IpPrefix>(1);\r
+ IpPrefix ipPrefix = new IpPrefix(\r
+ new Ipv4Prefix(ipPrefixProperty.getPropertyValues().getStringValue().get(0).getValue()));\r
+ ipPrefixes.add(ipPrefix);\r
+\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(ipPrefixes)\r
+ .build();\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+ Set<VirtualNodeId> handledVirtualSwitches = new HashSet<VirtualNodeId>();\r
+ VirtualPort virtualPort;\r
+ VirtualPort virtualPort1;\r
+ VirtualLink virtualLink;\r
+\r
+ for ( VirtualNode virtualSwitch : virtualSwitches ) {\r
+ virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .setExternalIpPrefixes(externalIpPrefixes)\r
+ .build();\r
+ virtualRouter.getVirtualPort().add(virtualPort);\r
+\r
+ virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualSwitch.getVirtualPort().add(virtualPort1);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualRouter.getNodeId())\r
+ .setSrcPortId(virtualPort.getPortId())\r
+ .setDestNodeId(virtualSwitch.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualSwitch.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualRouter.getNodeId())\r
+ .setDestPortId(virtualPort.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ for ( VirtualNode virtualSwitch1 : virtualSwitches ) {\r
+ if ( virtualSwitch1.getNodeId().equals(virtualSwitch.getNodeId()) ) {\r
+ continue;\r
+ }\r
+\r
+ if ( handledVirtualSwitches.contains(virtualSwitch1.getNodeId()) ) {\r
+ continue;\r
+ }\r
+\r
+ virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualSwitch.getVirtualPort().add(virtualPort);\r
+\r
+ virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualSwitch1.getVirtualPort().add(virtualPort1);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualSwitch.getNodeId())\r
+ .setSrcPortId(virtualPort.getPortId())\r
+ .setDestNodeId(virtualSwitch1.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualSwitch1.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualSwitch.getNodeId())\r
+ .setDestPortId(virtualPort.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+ }\r
+\r
+ handledVirtualSwitches.add(virtualSwitch.getNodeId());\r
+ }\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(1);\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vnode)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualRouter.getNodeId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(node.getNodeId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Node)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveLayer3Group(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ // TODO: 1、l3-group的sub-node可能是:l2-group、ext-group(l2)、ext-group(l3)。\r
+ // TODO: 将各个sub-node对应的gateway/access vrouter用vlinks连接(vrouter的vport)。\r
+ // TODO: 特别注意:需为ext-group(l2)创建gateway vrouter。\r
+ // TODO: 2、在data store中,创建vrouter、vports、vlinks。\r
+ // TODO: 3、将intent - vn mapping result写入data store。\r
+ // TODO: 4、将新vrouter、vlinks更新入user对应的算法实例。\r
+ // TODO: 通过算法实例,重新计算全网路由。\r
+ // TODO: 5、在data store中,新增 or 更新vroute。\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param generatingVirtualRouter TODO\r
+ */\r
+ protected void resolveExternalLayer2Group(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ boolean generatingVirtualRouter)\r
+ throws IntentResolutionException {\r
+ Property property = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("location"));\r
+\r
+ if ( null == property ) {\r
+ throw new IntentResolutionException("Can not get the location property of the node " +\r
+ node.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ PhysicalNodeId physicalNodeId = IntentResolverUtils\r
+ .generatePhysicalNodeIdFromNodeLocationProperty(property);\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement> physicalResourceRequirements =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue = new AttributeValueBuilder()\r
+ .setStringValue(physicalNodeId.getValue())\r
+ .build();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement physicalResourceRequirement =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue)\r
+ .setAttributeMatchPattern(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements.add(physicalResourceRequirement);\r
+\r
+ VirtualNode virtualNode = new VirtualNodeBuilder()\r
+ .setNodeId(new VirtualNodeId(UUID.randomUUID().toString()))\r
+ .setNodeType(generatingVirtualRouter ? VirtualNode.NodeType.Vrouter : VirtualNode.NodeType.Vswitch)\r
+ .setVirtualPort(new LinkedList<VirtualPort>())\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements)\r
+ .build();\r
+\r
+ virtualNetwork.getVirtualNodes().getVirtualNode().add(virtualNode);\r
+\r
+ ExternalMacAddresses externalMacAddresses = new ExternalMacAddressesBuilder()\r
+ .setExternalMacAddress(new ArrayList<MacAddress>(0))\r
+ .build();\r
+\r
+ ExternalIpPrefixes externalIpPrefixes = null;\r
+\r
+ if ( generatingVirtualRouter ) {\r
+ Property property1 = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("ip-prefix"));\r
+\r
+ if ( null != property1 ) {\r
+ List<IpPrefix> ipPrefixes = new ArrayList<IpPrefix>(1);\r
+ IpPrefix ipPrefix = new IpPrefix(\r
+ new Ipv4Prefix(property1.getPropertyValues().getStringValue().get(0).getValue()));\r
+ ipPrefixes.add(ipPrefix);\r
+\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(ipPrefixes)\r
+ .build();\r
+ } else {\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(new ArrayList<IpPrefix>(0))\r
+ .build();\r
+ }\r
+ }\r
+\r
+ List<PhysicalResourceRequirement> physicalResourceRequirements1 =\r
+ new ArrayList<PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue1 = new AttributeValueBuilder()\r
+ .setStringValue(property.getPropertyValues().getStringValue().get(0).getValue())\r
+ .build();\r
+ PhysicalResourceRequirement physicalResourceRequirement1 = new PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue1)\r
+ .setAttributeMatchPattern(PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements1.add(physicalResourceRequirement1);\r
+\r
+ VirtualPort virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.External)\r
+ .setExternalMacAddresses(externalMacAddresses)\r
+ .setExternalIpPrefixes(externalIpPrefixes)\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements1)\r
+ .build();\r
+\r
+ virtualNode.getVirtualPort().add(virtualPort);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(1);\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vport)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPort.getPortId().getValue()))\r
+ .setParentVirtualResourceEntityId(new VirtualResourceEntityId(virtualNode.getNodeId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(node.getNodeId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Node)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ userIntentVnMapping.getIntentVnMappingResult().add(intentVnMappingResult);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveExternalLayer3Group(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ Property property = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("location"));\r
+\r
+ if ( null == property ) {\r
+ throw new IntentResolutionException("Can not get the location property of the node " +\r
+ node.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ PhysicalNodeId physicalNodeId = IntentResolverUtils\r
+ .generatePhysicalNodeIdFromNodeLocationProperty(property);\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement> physicalResourceRequirements =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue = new AttributeValueBuilder()\r
+ .setStringValue(physicalNodeId.getValue())\r
+ .build();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement physicalResourceRequirement =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue)\r
+ .setAttributeMatchPattern(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements.add(physicalResourceRequirement);\r
+\r
+ VirtualNode virtualNode = new VirtualNodeBuilder()\r
+ .setNodeId(new VirtualNodeId(UUID.randomUUID().toString()))\r
+ .setNodeType(VirtualNode.NodeType.Vrouter)\r
+ .setVirtualPort(new LinkedList<VirtualPort>())\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements)\r
+ .build();\r
+\r
+ virtualNetwork.getVirtualNodes().getVirtualNode().add(virtualNode);\r
+\r
+ ExternalIpPrefixes externalIpPrefixes;\r
+ Property property1 = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("ip-prefix"));\r
+\r
+ if ( null != property1 ) {\r
+ List<IpPrefix> ipPrefixes =\r
+ new ArrayList<IpPrefix>(property1.getPropertyValues().getStringValue().size());\r
+ IpPrefix ipPrefix;\r
+\r
+ for ( StringValue stringValue : property1.getPropertyValues().getStringValue() ) {\r
+ ipPrefix = new IpPrefix(new Ipv4Prefix(stringValue.getValue()));\r
+ ipPrefixes.add(ipPrefix);\r
+ }\r
+\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(ipPrefixes)\r
+ .build();\r
+ } else {\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(new ArrayList<IpPrefix>(0))\r
+ .build();\r
+ }\r
+\r
+ List<PhysicalResourceRequirement> physicalResourceRequirements1 =\r
+ new ArrayList<PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue1 = new AttributeValueBuilder()\r
+ .setStringValue(property.getPropertyValues().getStringValue().get(0).getValue())\r
+ .build();\r
+ PhysicalResourceRequirement physicalResourceRequirement1 = new PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue1)\r
+ .setAttributeMatchPattern(PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements1.add(physicalResourceRequirement1);\r
+\r
+ VirtualPort virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.External)\r
+ .setExternalIpPrefixes(externalIpPrefixes)\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements1)\r
+ .build();\r
+\r
+ virtualNode.getVirtualPort().add(virtualPort);\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(1);\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vport)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPort.getPortId().getValue()))\r
+ .setParentVirtualResourceEntityId(new VirtualResourceEntityId(virtualNode.getNodeId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(node.getNodeId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Node)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ userIntentVnMapping.getIntentVnMappingResult().add(intentVnMappingResult);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveServiceChainGroup(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ List<SubNode> subNodes = node.getSubNode();\r
+\r
+ if ( !subNodes.isEmpty() ) {\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ List<VirtualResource> virtualResources = new LinkedList<VirtualResource>();\r
+\r
+ if ( 1 == subNodes.size() ) {\r
+ SubNode subNode = subNodes.get(0);\r
+ IntentVnMappingResult intentVnMappingResult = IntentResolverUtils\r
+ .getIntentVnMappingResult(intentVnMappingResults, new IntentId(subNode.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + subNode.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ VirtualResource virtualResource = intentVnMappingResult.getVirtualResource().get(0);\r
+ virtualResource = new VirtualResourceBuilder(virtualResource)\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+ } else {\r
+ subNodes = IntentResolverUtils.sortSubNodes(subNodes);\r
+ List<Node> nodes = user.getObjects().getNode();\r
+ Iterator<SubNode> iterator = subNodes.iterator();\r
+ SubNode subNode1 = iterator.next();\r
+ SubNode subNode2;\r
+ IntentVnMappingResult intentVnMappingResult;\r
+ VirtualResource virtualResource;\r
+\r
+ if ( IntentResolverUtils.checkAllLayer2OperatingMode(subNodes, nodes) ) {\r
+ // TODO\r
+ } else if ( IntentResolverUtils.checkAllLayer3OperatingMode(subNodes, nodes) ) {\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+ List<VirtualPath> virtualPaths = virtualNetwork.getVirtualPaths().getVirtualPath();\r
+ VirtualNodeId virtualNodeId1;\r
+ VirtualNodeId virtualNodeId2;\r
+ VirtualNode virtualNode1 = null;\r
+ VirtualNode virtualNode2 = null;\r
+ VirtualPort virtualPort1;\r
+ VirtualPort virtualPort2;\r
+ VirtualLink virtualLink;\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink> virtualLinks1;\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink virtualLink1;\r
+ VirtualPath virtualPath;\r
+\r
+ intentVnMappingResult = IntentResolverUtils.getIntentVnMappingResult(intentVnMappingResults,\r
+ new IntentId(subNode1.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result for " +\r
+ "the node " + subNode1.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualResource = intentVnMappingResult.getVirtualResource().get(0);\r
+ virtualResource = new VirtualResourceBuilder(virtualResource)\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualNodeId1 = new VirtualNodeId(intentVnMappingResult.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+\r
+ while ( iterator.hasNext() ) {\r
+ subNode2 = iterator.next();\r
+ intentVnMappingResult = IntentResolverUtils.getIntentVnMappingResult(intentVnMappingResults,\r
+ new IntentId(subNode2.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result " +\r
+ "for the node " + subNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId2 = new VirtualNodeId(intentVnMappingResult.getVirtualResource().get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ virtualLink = IntentResolverUtils.getVirtualLink(virtualLinks, virtualNodeId1, virtualNodeId2);\r
+\r
+ if ( null == virtualLink ) {\r
+ if ( null == virtualNode1 ) {\r
+ virtualNode1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId1);\r
+\r
+ if ( null == virtualNode1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node " +\r
+ "created for the node " + subNode1.getNodeId().getValue() + ".");\r
+ }\r
+ }\r
+\r
+ virtualNode2 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId2);\r
+\r
+ if ( null == virtualNode2 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node created " +\r
+ "for the node " + subNode2.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualNode1.getVirtualPort().add(virtualPort1);\r
+\r
+ virtualPort2 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualNode2.getVirtualPort().add(virtualPort2);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualNodeId2)\r
+ .setSrcPortId(virtualPort2.getPortId())\r
+ .setDestNodeId(virtualNodeId1)\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualNodeId1)\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualNodeId2)\r
+ .setDestPortId(virtualPort2.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+ }\r
+\r
+ virtualLinks1 = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(1);\r
+ virtualLink1 = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLinkBuilder()\r
+ .setLinkId(virtualLink.getLinkId())\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualLinks1.add(virtualLink1);\r
+\r
+ virtualPath = new VirtualPathBuilder()\r
+ .setPathId(new VirtualPathId(UUID.randomUUID().toString()))\r
+ .setVirtualLink(virtualLinks1)\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualPaths.add(virtualPath);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vpath)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPath.getPathId().getValue()))\r
+ .setOrder((long) virtualResources.size())\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ virtualResource = intentVnMappingResult.getVirtualResource().get(0);\r
+ virtualResource = new VirtualResourceBuilder(virtualResource)\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setOrder((long) virtualResources.size())\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ subNode1 = subNode2;\r
+ virtualNodeId1 = virtualNodeId2;\r
+ virtualNode1 = virtualNode2;\r
+ virtualNode2 = null;\r
+ }\r
+ } else {\r
+ // TODO\r
+ }\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(node.getNodeId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Node)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveServiceFunction(User user, Node node, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ Property locationProperty = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("location"));\r
+\r
+ if ( null == locationProperty ) {\r
+ throw new IntentResolutionException("Can not get the location property of the node " +\r
+ node.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ Property operatingModeProperty = IntentResolverUtils\r
+ .getNodeProperty(node.getProperty(), new PropertyName("operating-mode"));\r
+\r
+ if ( null == operatingModeProperty ) {\r
+ throw new IntentResolutionException("Can not get the operating mode property of the node " +\r
+ node.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ PhysicalNodeId physicalNodeId = IntentResolverUtils\r
+ .generatePhysicalNodeIdFromNodeLocationProperty(locationProperty);\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement> physicalResourceRequirements =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue = new AttributeValueBuilder()\r
+ .setStringValue(physicalNodeId.getValue())\r
+ .build();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement physicalResourceRequirement =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue)\r
+ .setAttributeMatchPattern(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements.add(physicalResourceRequirement);\r
+\r
+ String operatingModePropertyValue =\r
+ operatingModeProperty.getPropertyValues().getStringValue().get(0).getValue();\r
+\r
+ VirtualNode virtualNode = new VirtualNodeBuilder()\r
+ .setNodeId(new VirtualNodeId(UUID.randomUUID().toString()))\r
+ .setNodeType(operatingModePropertyValue.equals("layer3") ?\r
+ VirtualNode.NodeType.Vrouter : VirtualNode.NodeType.Vswitch)\r
+ .setVirtualPort(new LinkedList<VirtualPort>())\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements)\r
+ .build();\r
+\r
+ virtualNetwork.getVirtualNodes().getVirtualNode().add(virtualNode);\r
+\r
+ ExternalMacAddresses externalMacAddresses = null;\r
+ ExternalIpPrefixes externalIpPrefixes = null;\r
+\r
+ if ( operatingModePropertyValue.equals("layer2") ) {\r
+ externalMacAddresses = new ExternalMacAddressesBuilder()\r
+ .setExternalMacAddress(new ArrayList<MacAddress>(0))\r
+ .build();\r
+ } else {\r
+ externalIpPrefixes = new ExternalIpPrefixesBuilder()\r
+ .setExternalIpPrefix(new ArrayList<IpPrefix>(0))\r
+ .build();\r
+ }\r
+\r
+ List<PhysicalResourceRequirement> physicalResourceRequirements1 =\r
+ new ArrayList<PhysicalResourceRequirement>(1);\r
+ AttributeValue attributeValue1 = new AttributeValueBuilder()\r
+ .setStringValue(locationProperty.getPropertyValues().getStringValue().get(0).getValue())\r
+ .build();\r
+ PhysicalResourceRequirement physicalResourceRequirement1 = new PhysicalResourceRequirementBuilder()\r
+ .setAttributeName(new AttributeName("location"))\r
+ .setAttributeValue(attributeValue1)\r
+ .setAttributeMatchPattern(PhysicalResourceRequirement.AttributeMatchPattern.Equal)\r
+ .build();\r
+ physicalResourceRequirements1.add(physicalResourceRequirement1);\r
+\r
+ VirtualPort virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.External)\r
+ .setExternalMacAddresses(externalMacAddresses)\r
+ .setExternalIpPrefixes(externalIpPrefixes)\r
+ .setPhysicalResourceRequirement(physicalResourceRequirements1)\r
+ .build();\r
+\r
+ virtualNode.getVirtualPort().add(virtualPort);\r
+\r
+ if ( operatingModePropertyValue.equals("layer2") ) {\r
+ // TODO: Connect to all virtual switches in the same layer2 group.\r
+ }\r
+\r
+ List<VirtualResource> virtualResources = new ArrayList<VirtualResource>(1);\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vport)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPort.getPortId().getValue()))\r
+ .setParentVirtualResourceEntityId(new VirtualResourceEntityId(virtualNode.getNodeId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(node.getNodeId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Node)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ userIntentVnMapping.getIntentVnMappingResult().add(intentVnMappingResult);\r
+\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLinkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPathBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPortBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResultBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResource;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResourceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ActionName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.IntentId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.action.instance.parameter.values.StringValue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.instance.ConditionSegment;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.operation.instance.Action;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.ArrayList;\r
+import java.util.LinkedList;\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+/**\r
+ * Resolve the user's operation intent that might act on the node, connection\r
+ * or flow. Perform the monitoring if the operation contains a condition which\r
+ * determines when to execute the operation. Resolve the actions included in\r
+ * the operation and decide how to implement them on the physical network.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class OperationResolver {\r
+ private static final Logger LOG = LoggerFactory.getLogger(OperationResolver.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ /**\r
+ * The action resolver to resolve actions in the operation.\r
+ */\r
+ private ActionResolver actionResolver;\r
+\r
+ public OperationResolver(DataBroker dataBroker) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+\r
+ actionResolver = new ActionResolver();\r
+\r
+ LOG.debug("Initialized the renderer common operation resolver.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Resolve the user's operation intent and perform the monitoring for\r
+ * the condition that it contains. Generate the intent mapping results\r
+ * for the operation in the data store, which denote how to implement\r
+ * it on the physical network.\r
+ *\r
+ * @param user The user for the operation.\r
+ * @param operation The operation to be resolved.\r
+ * @param virtualNetwork The virtual network for the user.\r
+ * @param userIntentVnMapping The intent-vn mapping for the user.\r
+ */\r
+ protected void resolveOperation(User user, Operation operation, VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ DataObject dataObject = IntentResolverUtils\r
+ .getObject(user.getObjects(), operation.getTargetObject());\r
+\r
+ if ( null == dataObject ) {\r
+ throw new IntentResolutionException("The target object of the operation " +\r
+ operation.getOperationId().getValue() + " does not exist.");\r
+ }\r
+\r
+ List<Operation> operations = user.getOperations().getOperation();\r
+ List<Operation> sameTargetObjectOperations = IntentResolverUtils\r
+ .getSameTargetObjectOperations(operations, operation);\r
+\r
+ if ( !sameTargetObjectOperations.isEmpty() ) {\r
+ List<Operation> greaterPriorityOperations = new LinkedList<Operation>();\r
+ List<Operation> equalPriorityOperations = new LinkedList<Operation>();\r
+\r
+ IntentResolverUtils.getGreaterAndEqualPriorityOperations(sameTargetObjectOperations,\r
+ operation, greaterPriorityOperations, equalPriorityOperations);\r
+\r
+ if ( greaterPriorityOperations.isEmpty() ) {\r
+ if ( !equalPriorityOperations.isEmpty() ) {\r
+ Operation conflictingOperation = IntentResolverUtils\r
+ .getConflictingOperation(equalPriorityOperations, operation);\r
+\r
+ if ( null != conflictingOperation ) {\r
+ throw new IntentResolutionException("The operation " +\r
+ operation.getOperationId().getValue() + " conflicts with the one " +\r
+ conflictingOperation.getOperationId().getValue() + ".");\r
+ }\r
+ }\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+\r
+ List<ConditionSegment> conditionSegments = operation.getConditionSegment();\r
+\r
+ if ( null != conditionSegments && !conditionSegments.isEmpty() ) {\r
+ // TODO\r
+\r
+ return;\r
+ }\r
+\r
+ List<Action> actions = operation.getAction();\r
+\r
+ if ( null != actions && !actions.isEmpty() ) {\r
+ if ( dataObject instanceof Node ) {\r
+ actionResolver.resolveActions(user, operation, (Node)dataObject,\r
+ virtualNetwork, userIntentVnMapping);\r
+ } else if ( dataObject instanceof Connection ) {\r
+ actionResolver.resolveActions(user, operation, (Connection)dataObject,\r
+ virtualNetwork, userIntentVnMapping);\r
+ } else {\r
+ actionResolver.resolveActions(user, operation, (Flow)dataObject,\r
+ virtualNetwork, userIntentVnMapping);\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Perform the monitoring for the operation that contains a condition\r
+ * which determines when to execute the operation.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class ConditionMonitor {\r
+ // TODO\r
+ }\r
+\r
+ /**\r
+ * Resolve the actions included in the operation and decide how to\r
+ * implement them on the physical network.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class ActionResolver {\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param operation TODO\r
+ * @param node TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveActions(User user, Operation operation, Node node,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ // TODO\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param operation TODO\r
+ * @param connection TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveActions(User user, Operation operation, Connection connection,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ // TODO\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param operation TODO\r
+ * @param flow TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ protected void resolveActions(User user, Operation operation, Flow flow,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ List<Action> actions = operation.getAction();\r
+\r
+ ActionName actionName = new ActionName("go-through");\r
+ Action goThroughAction = IntentResolverUtils.getAction(actions, actionName);\r
+\r
+ if ( null != goThroughAction ) {\r
+ resolveGoThroughAction(user, operation, flow, goThroughAction,\r
+ virtualNetwork, userIntentVnMapping);\r
+\r
+ return;\r
+ }\r
+\r
+ throw new IntentResolutionException("Unsupported action combination.");\r
+\r
+// return;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param user TODO\r
+ * @param operation TODO\r
+ * @param flow TODO\r
+ * @param goThroughAction TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ */\r
+ private void resolveGoThroughAction(User user, Operation operation, Flow flow,\r
+ Action goThroughAction,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping)\r
+ throws IntentResolutionException {\r
+ List<StringValue> parameterValues = goThroughAction.getParameterValues().getStringValue();\r
+\r
+ if ( !parameterValues.isEmpty() ) {\r
+ List<Node> nodes = user.getObjects().getNode();\r
+\r
+ if ( null == nodes || nodes.isEmpty() ) {\r
+ throw new IntentResolutionException("The nodes specified by the action parameters " +\r
+ "of the operation " + operation.getOperationId().getValue() + " does not exist.");\r
+ }\r
+\r
+ NodeId nodeId = new NodeId(parameterValues.get(0).getValue());\r
+ Node node = IntentResolverUtils.getNode(nodes, nodeId);\r
+\r
+ if ( null == node ) {\r
+ throw new IntentResolutionException("The node " + nodeId.getValue() + " specified by the" +\r
+ " action parameter of the operation " + operation.getOperationId().getValue() +\r
+ " does not exist.");\r
+ }\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+ List<VirtualPath> virtualPaths = virtualNetwork.getVirtualPaths().getVirtualPath();\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ List<VirtualResource> virtualResources = null;\r
+\r
+ if ( node.getNodeType().equals(new NodeType("chain-group")) ) {\r
+ if ( IntentResolverUtils.checkAllLayer2OperatingMode(node.getSubNode(), nodes) ) {\r
+ // TODO\r
+ } else if ( IntentResolverUtils.checkAllLayer3OperatingMode(node.getSubNode(), nodes) ) {\r
+ IntentVnMappingResult intentVnMappingResult = IntentResolverUtils.getIntentVnMappingResult(\r
+ intentVnMappingResults, new IntentId(node.getNodeId().getValue()));\r
+\r
+ if ( null == intentVnMappingResult ) {\r
+ throw new IntentResolutionException("Can not get the intent-vn mapping result " +\r
+ "for the node " + node.getNodeId().getValue() + ".");\r
+ }\r
+\r
+ VirtualNode sourceVirtualNode = IntentResolverUtils.getSourceVirtualRouterOfFlow(\r
+ virtualNodes, flow, nodes, intentVnMappingResults);\r
+\r
+ if ( null == sourceVirtualNode ) {\r
+ throw new IntentResolutionException("Can not get the source virtual node " +\r
+ "of the flow " + flow.getFlowId().getValue() + ".");\r
+ }\r
+\r
+ VirtualNode destinationVirtualNode = IntentResolverUtils.getDestinationVirtualRouterOfFlow(\r
+ virtualNodes, flow, nodes, intentVnMappingResults);\r
+\r
+ if ( null == destinationVirtualNode ) {\r
+ throw new IntentResolutionException("Can not get the destination virtual node " +\r
+ "of the flow " + flow.getFlowId().getValue() + ".");\r
+ }\r
+\r
+ List<VirtualResource> virtualResources1 = IntentResolverUtils\r
+ .sortVirtualResources(intentVnMappingResult.getVirtualResource());\r
+\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(virtualResources1.get(0)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualNode = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualNode ) {\r
+ throw new IntentResolutionException("Can not get the virtual node" +\r
+ " created for the first sub-node of the node " +\r
+ intentVnMappingResult.getIntentId().getValue() + ".");\r
+ }\r
+\r
+ virtualNodeId = new VirtualNodeId(virtualResources1.get(virtualResources1.size() - 1)\r
+ .getParentVirtualResourceEntityId().getValue());\r
+ VirtualNode virtualNode1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);\r
+\r
+ if ( null == virtualNode1 ) {\r
+ throw new IntentResolutionException("Can not get the virtual node" +\r
+ " created for the last sub-node of the node " +\r
+ intentVnMappingResult.getIntentId().getValue() + ".");\r
+ }\r
+\r
+ virtualResources = new ArrayList<VirtualResource>(virtualResources1.size() + 2);\r
+ VirtualLink virtualLink = IntentResolverUtils.getVirtualLink(virtualLinks,\r
+ sourceVirtualNode.getNodeId(), virtualNode.getNodeId());\r
+\r
+ if ( null == virtualLink ) {\r
+ VirtualPort virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ sourceVirtualNode.getVirtualPort().add(virtualPort);\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualNode.getVirtualPort().add(virtualPort1);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualNode.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(sourceVirtualNode.getNodeId())\r
+ .setDestPortId(virtualPort.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(sourceVirtualNode.getNodeId())\r
+ .setSrcPortId(virtualPort.getPortId())\r
+ .setDestNodeId(virtualNode.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink> virtualLinks1 =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(1);\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink virtualLink1 =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLinkBuilder()\r
+ .setLinkId(virtualLink.getLinkId())\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualLinks1.add(virtualLink1);\r
+\r
+ VirtualPath virtualPath = new VirtualPathBuilder()\r
+ .setPathId(new VirtualPathId(UUID.randomUUID().toString()))\r
+ .setVirtualLink(virtualLinks1)\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualPaths.add(virtualPath);\r
+\r
+ VirtualResource virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vpath)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPath.getPathId().getValue()))\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+\r
+ for ( VirtualResource virtualResource1 : virtualResources1 ) {\r
+ virtualResource = new VirtualResourceBuilder(virtualResource1)\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setOrder((long)virtualResources.size())\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+ }\r
+\r
+ virtualLink = IntentResolverUtils.getVirtualLink(virtualLinks,\r
+ virtualNode1.getNodeId(), destinationVirtualNode.getNodeId());\r
+\r
+ if ( null == virtualLink ) {\r
+ VirtualPort virtualPort = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ virtualNode1.getVirtualPort().add(virtualPort);\r
+\r
+ VirtualPort virtualPort1 = new VirtualPortBuilder()\r
+ .setPortId(new VirtualPortId(UUID.randomUUID().toString()))\r
+ .setPortType(VirtualPort.PortType.Internal)\r
+ .build();\r
+ destinationVirtualNode.getVirtualPort().add(virtualPort1);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(destinationVirtualNode.getNodeId())\r
+ .setSrcPortId(virtualPort1.getPortId())\r
+ .setDestNodeId(virtualNode1.getNodeId())\r
+ .setDestPortId(virtualPort.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))\r
+ .setSrcNodeId(virtualNode1.getNodeId())\r
+ .setSrcPortId(virtualPort.getPortId())\r
+ .setDestNodeId(destinationVirtualNode.getNodeId())\r
+ .setDestPortId(virtualPort1.getPortId())\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+ }\r
+\r
+ virtualLinks1 = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(1);\r
+ virtualLink1 = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLinkBuilder()\r
+ .setLinkId(virtualLink.getLinkId())\r
+ .setOrder(0L)\r
+ .build();\r
+ virtualLinks1.add(virtualLink1);\r
+\r
+ virtualPath = new VirtualPathBuilder()\r
+ .setPathId(new VirtualPathId(UUID.randomUUID().toString()))\r
+ .setVirtualLink(virtualLinks1)\r
+ .setBandwidth(0L)\r
+ .build();\r
+ virtualPaths.add(virtualPath);\r
+\r
+ virtualResource = new VirtualResourceBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResource.VirtualResourceType.Vpath)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPath.getPathId().getValue()))\r
+ .setOrder((long) virtualResources.size())\r
+ .build();\r
+ virtualResources.add(virtualResource);\r
+ } else {\r
+ // TODO\r
+ }\r
+ } else {\r
+ // TODO\r
+ }\r
+\r
+ IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()\r
+ .setIntentId(new IntentId(operation.getOperationId().getValue()))\r
+ .setIntentType(IntentVnMappingResult.IntentType.Operation)\r
+ .setVirtualResource(virtualResources)\r
+ .build();\r
+\r
+ intentVnMappingResults.add(intentVnMappingResult);\r
+ }\r
+\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.algorithm;\r
+\r
+/**\r
+ * An edge in the network topology.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class Edge {\r
+ private String id;\r
+ private String src;\r
+ private String dest;\r
+ private long metric;\r
+ private long bandwidth;\r
+\r
+ public Edge(String id, String src, String dest, long metric, long bandwidth) {\r
+ super();\r
+\r
+ this.id = id;\r
+ this.src = src;\r
+ this.dest = dest;\r
+ this.metric = metric;\r
+ this.bandwidth = bandwidth;\r
+\r
+ return;\r
+ }\r
+\r
+ public String getId() {\r
+ return id;\r
+ }\r
+\r
+ public String getSrc() {\r
+ return src;\r
+ }\r
+\r
+ public String getDest() {\r
+ return dest;\r
+ }\r
+\r
+ public long getMetric() {\r
+ return metric;\r
+ }\r
+\r
+ public long getBandwidth() {\r
+ return bandwidth;\r
+ }\r
+\r
+ public void setMetric(long metric) {\r
+ this.metric = metric;\r
+\r
+ return;\r
+ }\r
+\r
+ public void setBandwidth(long bandwidth) {\r
+ this.bandwidth = bandwidth;\r
+\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ return ((Edge)obj).getId().equals(id);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "Edge{" +\r
+ "id='" + id + '\'' +\r
+ ", src='" + src + '\'' +\r
+ ", dest='" + dest + '\'' +\r
+ ", metric=" + metric +\r
+ ", bandwidth=" + bandwidth +\r
+ '}';\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.algorithm;\r
+\r
+import edu.uci.ics.jung.algorithms.filters.EdgePredicateFilter;\r
+import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;\r
+import edu.uci.ics.jung.graph.DirectedSparseGraph;\r
+import edu.uci.ics.jung.graph.Graph;\r
+import edu.uci.ics.jung.graph.util.EdgeType;\r
+import org.apache.commons.collections15.Predicate;\r
+import org.apache.commons.collections15.Transformer;\r
+\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+/**\r
+ * Implement the SPF and CSPF algorithms based on the Dijkstra's algorithm.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class RoutingAlgorithm {\r
+ /**\r
+ * The current network topology graph.\r
+ */\r
+ private Graph<Vertex, Edge> graph;\r
+\r
+ /**\r
+ * The Dijkstra shortest path algorithm instance.\r
+ */\r
+ private DijkstraShortestPath<Vertex, Edge> dijkstraShortestPath;\r
+\r
+ public RoutingAlgorithm() {\r
+ super();\r
+\r
+ graph = new DirectedSparseGraph<Vertex, Edge>();\r
+ dijkstraShortestPath = new DijkstraShortestPath<Vertex, Edge>(graph, new Transformer<Edge, Number>() {\r
+ @Override\r
+ public Number transform(Edge edge) {\r
+ return edge.getMetric();\r
+ }\r
+ }, false);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Get the vertex with the given id from the network topology graph.\r
+ *\r
+ * @param vertexId The given vertex id.\r
+ * @return The vertex with the given id.\r
+ */\r
+ public Vertex getVertex(String vertexId) {\r
+ for ( Vertex vertex : graph.getVertices() ) {\r
+ if ( vertex.getId().equals(vertexId) ) {\r
+ return vertex;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Get the edge with the given id from the network topology graph.\r
+ *\r
+ * @param edgeId The given edge id.\r
+ * @return The edge with the given id.\r
+ */\r
+ public Edge getEdge(String edgeId) {\r
+ for ( Edge edge : graph.getEdges() ) {\r
+ if ( edge.getId().equals(edgeId) ) {\r
+ return edge;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Get all vertices from the network topology graph.\r
+ *\r
+ * @return The collection of all vertices.\r
+ */\r
+ public Collection<Vertex> getVertices() {\r
+ return graph.getVertices();\r
+ }\r
+\r
+ /**\r
+ * Add a vertex into the network topology graph.\r
+ *\r
+ * @param vertex The vertex to be added.\r
+ */\r
+ public void addVertex(Vertex vertex) {\r
+ graph.addVertex(vertex);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Add an edge into the network topology graph.\r
+ *\r
+ * @param edge The edge to be added.\r
+ */\r
+ public void addEdge(Edge edge) {\r
+ graph.addEdge(edge, getVertex(edge.getSrc()), getVertex(edge.getDest()), EdgeType.DIRECTED);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Update an edge in the network topology graph with the new one.\r
+ *\r
+ * @param newEdge The given new edge.\r
+ */\r
+ public void updateEdge(Edge newEdge) {\r
+ Edge edge = getEdge(newEdge.getId());\r
+\r
+ edge.setMetric(newEdge.getMetric());\r
+ edge.setBandwidth(newEdge.getBandwidth());\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Remove the vertex with the given id from the network topology graph.\r
+ *\r
+ * @param vertexId The given vertex id.\r
+ */\r
+ public void removeVertex(String vertexId) {\r
+ Vertex vertex = getVertex(vertexId);\r
+\r
+ if ( null != vertex ) {\r
+ graph.removeVertex(vertex);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Remove the edge with the given id from the network topology graph.\r
+ *\r
+ * @param edgeId The given edge id.\r
+ */\r
+ public void removeEdge(String edgeId) {\r
+ Edge edge = getEdge(edgeId);\r
+\r
+ if ( null != edge ) {\r
+ graph.removeEdge(edge);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Compute a shortest path from the given source vertex to target\r
+ * one without any constraint.\r
+ *\r
+ * @param source The given source vertex.\r
+ * @param target The given target vertex.\r
+ * @return A list of the edges on the shortest path, in order of\r
+ * their occurrence on this path.\r
+ */\r
+ public List<Edge> computePath(Vertex source, Vertex target) {\r
+ return dijkstraShortestPath.getPath(source, target);\r
+ }\r
+\r
+ /**\r
+ * Compute a shortest path with the given bandwidth from the given\r
+ * source vertex to target one.\r
+ *\r
+ * @param source The given source vertex.\r
+ * @param target The given target vertex.\r
+ * @param bandwidth The given bandwidth for the path.\r
+ * @return A list of the edges on the shortest path, in order of\r
+ * their occurrence on this path.\r
+ */\r
+ public List<Edge> computePath(Vertex source, Vertex target, final long bandwidth) {\r
+ EdgePredicateFilter<Vertex, Edge> edgeEdgePredicateFilter = new EdgePredicateFilter<Vertex, Edge>(new Predicate<Edge>() {\r
+ @Override\r
+ public boolean evaluate(Edge edge) {\r
+ return edge.getBandwidth() >= bandwidth;\r
+ }\r
+ });\r
+\r
+ Graph<Vertex, Edge> filteredGraph = edgeEdgePredicateFilter.transform(graph);\r
+ DijkstraShortestPath<Vertex, Edge> tempDijkstraShortestPath = new DijkstraShortestPath<Vertex, Edge>(filteredGraph, new Transformer<Edge, Number>() {\r
+ @Override\r
+ public Number transform(Edge edge) {\r
+ return edge.getMetric();\r
+ }\r
+ }, false);\r
+\r
+ return tempDijkstraShortestPath.getPath(source, target);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "RoutingAlgorithm{" +\r
+ "vertices=" + graph.getVertices() +\r
+ ", edges=" + graph.getEdges() +\r
+ '}';\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.algorithm;\r
+\r
+/**\r
+ * A vertex in the network topology.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class Vertex {\r
+ private String id;\r
+\r
+ public Vertex(String id) {\r
+ super();\r
+\r
+ this.id = id;\r
+\r
+ return;\r
+ }\r
+\r
+ public String getId() {\r
+ return id;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ return ((Vertex)obj).getId().equals(id);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "Vertex{" +\r
+ "id='" + id + '\'' +\r
+ '}';\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.computation;\r
+\r
+import com.google.common.base.Optional;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.nemo.intent.algorithm.Edge;\r
+import org.opendaylight.nemo.intent.algorithm.RoutingAlgorithm;\r
+import org.opendaylight.nemo.intent.algorithm.Vertex;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalLinks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalPaths;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPathBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLinkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalLinkId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalNodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalPathId;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.*;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+/**\r
+ * The physical network computation unit implements the following functions:\r
+ * (1) Maintain the underlying physical network topology information through\r
+ * subscribing from the data store.\r
+ * (2) Provide the tunnel computation with SLA constraints to the virtual\r
+ * network mapping computation unit.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class PNComputationUnit implements AutoCloseable {\r
+ private static final Logger LOG = LoggerFactory.getLogger(PNComputationUnit.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ /**\r
+ * The routing algorithm instance.\r
+ */\r
+ private RoutingAlgorithm routingAlgorithm;\r
+\r
+ /**\r
+ * The registration for the physical node change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> physicalNodeChangeListenerReg;\r
+\r
+ /**\r
+ * The registration for the physical link change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> physicalLinkChangeListenerReg;\r
+\r
+ /**\r
+ * The registration for the physical path change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> physicalPathChangeListenerReg;\r
+\r
+ public PNComputationUnit(DataBroker dataBroker) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+ routingAlgorithm = new RoutingAlgorithm();\r
+\r
+ InstanceIdentifier<PhysicalNode> physicalNodeIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalNodes.class)\r
+ .child(PhysicalNode.class)\r
+ .build();\r
+ InstanceIdentifier<PhysicalLink> physicalLinkIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalLinks.class)\r
+ .child(PhysicalLink.class)\r
+ .build();\r
+ InstanceIdentifier<PhysicalPath> physicalPathIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalPaths.class)\r
+ .child(PhysicalPath.class)\r
+ .build();\r
+\r
+ physicalNodeChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,\r
+ physicalNodeIid, new PhysicalNodeChangeListener(), DataChangeScope.BASE);\r
+ physicalLinkChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,\r
+ physicalLinkIid, new PhysicalLinkChangeListener(), DataChangeScope.BASE);\r
+ physicalPathChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,\r
+ physicalPathIid, new PhysicalPathChangeListener(), DataChangeScope.BASE);\r
+\r
+ ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();\r
+\r
+ InstanceIdentifier<PhysicalNodes> physicalNodesIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalNodes.class)\r
+ .build();\r
+ Optional<PhysicalNodes> result;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, physicalNodesIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new RuntimeException("Can not read the physical nodes.");\r
+ }\r
+\r
+ if ( result.isPresent() ) {\r
+ PhysicalNodes physicalNodes = result.get();\r
+ Vertex vertex;\r
+\r
+ for ( PhysicalNode physicalNode : physicalNodes.getPhysicalNode() ) {\r
+ vertex = new Vertex(physicalNode.getNodeId().getValue());\r
+ routingAlgorithm.addVertex(vertex);\r
+ }\r
+ }\r
+\r
+ InstanceIdentifier<PhysicalLinks> physicalLinksIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalLinks.class)\r
+ .build();\r
+ Optional<PhysicalLinks> result1;\r
+\r
+ try {\r
+ result1 = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, physicalLinksIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new RuntimeException("Can not read the physical links.");\r
+ }\r
+\r
+ if ( result1.isPresent() ) {\r
+ PhysicalLinks physicalLinks = result1.get();\r
+ Edge edge;\r
+\r
+ for ( PhysicalLink physicalLink : physicalLinks.getPhysicalLink() ) {\r
+ edge = new Edge(physicalLink.getLinkId().getValue(), physicalLink.getSrcNodeId().getValue(),\r
+ physicalLink.getDestNodeId().getValue(), physicalLink.getMetric(),\r
+ physicalLink.getBandwidth());\r
+ routingAlgorithm.addEdge(edge);\r
+ }\r
+ }\r
+\r
+ LOG.debug("Initialized the physical network computation unit.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Compute a shortest physical path from the given source vertex to\r
+ * target one without any constraint.\r
+ *\r
+ * @param source The given source physical node id.\r
+ * @param target The given target physical node id.\r
+ * @return The physical path if successful,or null otherwise.\r
+ */\r
+ protected PhysicalPath computePath(PhysicalNodeId source, PhysicalNodeId target) {\r
+ List<Edge> edges = routingAlgorithm.computePath(routingAlgorithm.getVertex(source.getValue()),\r
+ routingAlgorithm.getVertex(target.getValue()));\r
+\r
+ if ( null == edges || edges.isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink> physicalLinks =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>(edges.size());\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink physicalLink;\r
+ long metric = 0;\r
+ long delay = 0;\r
+\r
+ for ( Edge edge : edges ) {\r
+ physicalLink = new PhysicalLinkBuilder()\r
+ .setLinkId(new PhysicalLinkId(edge.getId()))\r
+ .setOrder((long) physicalLinks.size())\r
+ .build();\r
+ physicalLinks.add(physicalLink);\r
+\r
+ metric += edge.getMetric();\r
+// delay += edge.getDelay();\r
+ }\r
+\r
+ PhysicalPath physicalPath = new PhysicalPathBuilder()\r
+ .setPathId(new PhysicalPathId(UUID.randomUUID().toString()))\r
+ .setPhysicalLink(physicalLinks)\r
+ .setMetric(metric)\r
+ .setBandwidth(0L)\r
+ .setDelay(delay)\r
+ .build();\r
+\r
+ return physicalPath;\r
+ }\r
+\r
+ /**\r
+ * Compute a shortest physical path with the given bandwidth from the\r
+ * given source vertex to target one.\r
+ *\r
+ * @param source The given source physical node id.\r
+ * @param target The given target physical node id.\r
+ * @param bandwidth The given bandwidth for the physical path.\r
+ * @return The physical path if successful,or null otherwise.\r
+ */\r
+ protected PhysicalPath computePath(PhysicalNodeId source, PhysicalNodeId target, long bandwidth) {\r
+ List<Edge> edges = routingAlgorithm.computePath(routingAlgorithm.getVertex(source.getValue()),\r
+ routingAlgorithm.getVertex(target.getValue()), bandwidth);\r
+\r
+ if ( null == edges || edges.isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink> physicalLinks =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>(edges.size());\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink physicalLink;\r
+ long metric = 0;\r
+ long delay = 0;\r
+\r
+ for ( Edge edge : edges ) {\r
+ edge.setBandwidth(edge.getBandwidth() - bandwidth);\r
+ routingAlgorithm.updateEdge(edge);\r
+\r
+ physicalLink = new PhysicalLinkBuilder()\r
+ .setLinkId(new PhysicalLinkId(edge.getId()))\r
+ .setOrder((long) physicalLinks.size())\r
+ .build();\r
+ physicalLinks.add(physicalLink);\r
+\r
+ metric += edge.getMetric();\r
+// delay += edge.getDelay();\r
+ }\r
+\r
+ PhysicalPath physicalPath = new PhysicalPathBuilder()\r
+ .setPathId(new PhysicalPathId(UUID.randomUUID().toString()))\r
+ .setPhysicalLink(physicalLinks)\r
+ .setMetric(metric)\r
+ .setBandwidth(bandwidth)\r
+ .setDelay(delay)\r
+ .build();\r
+\r
+ return physicalPath;\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+ if ( null != physicalNodeChangeListenerReg ) {\r
+ physicalNodeChangeListenerReg.close();\r
+ }\r
+\r
+ if ( null != physicalLinkChangeListenerReg ) {\r
+ physicalLinkChangeListenerReg.close();\r
+ }\r
+\r
+ if ( null != physicalPathChangeListenerReg ) {\r
+ physicalPathChangeListenerReg.close();\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to physical nodes being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalNodeChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+\r
+ if ( null != createdData && !createdData.isEmpty() ) {\r
+ PhysicalNode physicalNode;\r
+ Vertex vertex;\r
+\r
+ for ( DataObject dataObject : createdData.values() ) {\r
+ if ( dataObject instanceof PhysicalNode ) {\r
+ physicalNode = (PhysicalNode)dataObject;\r
+ vertex = new Vertex(physicalNode.getNodeId().getValue());\r
+\r
+ routingAlgorithm.addVertex(vertex);\r
+ }\r
+ }\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+\r
+ if ( null != dataObject && dataObject instanceof PhysicalNode ) {\r
+ routingAlgorithm.removeVertex(((PhysicalNode)dataObject).getNodeId().getValue());\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to physical links being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalLinkChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+\r
+ if ( null != createdData && !createdData.isEmpty() ) {\r
+ PhysicalLink physicalLink;\r
+ Edge edge;\r
+\r
+ for ( DataObject dataObject : createdData.values() ) {\r
+ if ( dataObject instanceof PhysicalLink ) {\r
+ physicalLink = (PhysicalLink)dataObject;\r
+ edge = new Edge(physicalLink.getLinkId().getValue(), physicalLink.getSrcNodeId().getValue(),\r
+ physicalLink.getDestNodeId().getValue(), physicalLink.getMetric(),\r
+ physicalLink.getBandwidth());\r
+\r
+ routingAlgorithm.addEdge(edge);\r
+ }\r
+ }\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();\r
+\r
+ if ( null != updatedData && !updatedData.isEmpty() ) {\r
+ PhysicalLink physicalLink;\r
+ Edge edge;\r
+\r
+ for ( DataObject dataObject : updatedData.values() ) {\r
+ if ( dataObject instanceof PhysicalLink ) {\r
+ physicalLink = (PhysicalLink)dataObject;\r
+ edge = new Edge(physicalLink.getLinkId().getValue(), physicalLink.getSrcNodeId().getValue(),\r
+ physicalLink.getDestNodeId().getValue(), physicalLink.getMetric(),\r
+ physicalLink.getBandwidth());\r
+\r
+ routingAlgorithm.updateEdge(edge);\r
+ }\r
+ }\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+\r
+ if ( null != dataObject && dataObject instanceof PhysicalLink ) {\r
+ routingAlgorithm.removeEdge(((PhysicalLink)dataObject).getLinkId().getValue());\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to physical paths being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalPathChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+ PhysicalPath physicalPath;\r
+ long bandwidth;\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink> physicalLinks;\r
+ Edge edge;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+\r
+ if ( null != dataObject && dataObject instanceof PhysicalPath ) {\r
+ physicalPath = (PhysicalPath)dataObject;\r
+ bandwidth = physicalPath.getBandwidth();\r
+\r
+ if ( 0 < bandwidth ) {\r
+ physicalLinks = physicalPath.getPhysicalLink();\r
+\r
+ if ( null != physicalLinks && !physicalLinks.isEmpty() ) {\r
+ for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink\r
+ physicalLink : physicalLinks ) {\r
+ edge = routingAlgorithm.getEdge(physicalLink.getLinkId().getValue());\r
+\r
+ if ( null != edge ) {\r
+ edge.setBandwidth(edge.getBandwidth() + bandwidth);\r
+ routingAlgorithm.updateEdge(edge);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.computation;\r
+\r
+import com.google.common.base.Optional;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.nemo.intent.algorithm.Edge;\r
+import org.opendaylight.nemo.intent.algorithm.RoutingAlgorithm;\r
+import org.opendaylight.nemo.intent.algorithm.Vertex;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.VirtualNetworks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.VirtualLinks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.VirtualNodes;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.VirtualPaths;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.VirtualRoutes;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPathBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPathKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.routes.VirtualRoute;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.routes.VirtualRouteBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.routes.VirtualRouteKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLinkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualLinkId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNetworkId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualPathId;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.*;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+/**\r
+ * The virtual network computation unit implements the following functions:\r
+ * (1) Maintain a user's virtual network topology information generated in\r
+ * terms of the user's intents through subscribing from the data store.\r
+ * (2) Automatically recompute all routes of the virtual network when it\r
+ * changed, and store or update the routes into the data store.\r
+ * (3) Provide the path computation with SLA constraints to any other modules\r
+ * that need it.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class VNComputationUnit implements AutoCloseable {\r
+ private static final Logger LOG = LoggerFactory.getLogger(VNComputationUnit.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ /**\r
+ * The user id for the virtual network maintained by\r
+ * this computation unit.\r
+ */\r
+ private UserId userId;\r
+\r
+ /**\r
+ * The routing algorithm instance.\r
+ */\r
+ private RoutingAlgorithm routingAlgorithm;\r
+\r
+ /**\r
+ * The virtual routers in the virtual network.\r
+ */\r
+ private Set<VirtualNodeId> virtualRouters;\r
+\r
+ /**\r
+ * The registration for the virtual node change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> virtualNodeChangeListenerReg;\r
+\r
+ /**\r
+ * The registration for the virtual link change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> virtualLinkChangeListenerReg;\r
+\r
+ public VNComputationUnit(DataBroker dataBroker, UserId userId) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+ this.userId = userId;\r
+ routingAlgorithm = new RoutingAlgorithm();\r
+ virtualRouters = new HashSet<VirtualNodeId>();\r
+\r
+ VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(new VirtualNetworkId(userId.getValue()));\r
+ InstanceIdentifier<VirtualNode> virtualNodeIid = InstanceIdentifier\r
+ .builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .child(VirtualNodes.class)\r
+ .child(VirtualNode.class)\r
+ .build();\r
+ InstanceIdentifier<VirtualLink> virtualLinkIid = InstanceIdentifier\r
+ .builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .child(VirtualLinks.class)\r
+ .child(VirtualLink.class)\r
+ .build();\r
+\r
+ virtualNodeChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,\r
+ virtualNodeIid, new VirtualNodeChangeListener(), DataChangeScope.BASE);\r
+ virtualLinkChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,\r
+ virtualLinkIid, new VirtualLinkChangeListener(), DataChangeScope.BASE);\r
+\r
+ LOG.debug("Initialized the virtual network computation unit for the user {}.", userId.getValue());\r
+\r
+ return;\r
+ }\r
+\r
+ public VNComputationUnit(DataBroker dataBroker, VirtualNetwork virtualNetwork) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+ userId = virtualNetwork.getUserId();\r
+ routingAlgorithm = new RoutingAlgorithm();\r
+ virtualRouters = new HashSet<VirtualNodeId>();\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ Vertex vertex;\r
+\r
+ for ( VirtualNode virtualNode : virtualNodes ) {\r
+ vertex = new Vertex(virtualNode.getNodeId().getValue());\r
+ routingAlgorithm.addVertex(vertex);\r
+\r
+ if ( VirtualNode.NodeType.Vrouter == virtualNode.getNodeType() ) {\r
+ virtualRouters.add(virtualNode.getNodeId());\r
+ }\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+ Edge edge;\r
+\r
+ for ( VirtualLink virtualLink : virtualLinks ) {\r
+ edge = new Edge(virtualLink.getLinkId().getValue(), virtualLink.getSrcNodeId().getValue(),\r
+ virtualLink.getDestNodeId().getValue(), virtualLink.getMetric(),\r
+ virtualLink.getBandwidth());\r
+ routingAlgorithm.addEdge(edge);\r
+ }\r
+\r
+// computeRoute(virtualNetwork);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Compute a shortest virtual path from the given source vertex to\r
+ * target one without any constraint.\r
+ *\r
+ * @param source The given source virtual node id.\r
+ * @param target The given target virtual node id.\r
+ * @return The virtual path if successful,or null otherwise.\r
+ */\r
+ public VirtualPath computePath(VirtualNodeId source, VirtualNodeId target) {\r
+ List<Edge> edges = routingAlgorithm.computePath(routingAlgorithm.getVertex(source.getValue()),\r
+ routingAlgorithm.getVertex(target.getValue()));\r
+\r
+ if ( null == edges || edges.isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink> virtualLinks =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(edges.size());\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink virtualLink;\r
+ long metric = 0;\r
+ long delay = 0;\r
+\r
+ for ( Edge edge : edges ) {\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(edge.getId()))\r
+ .setOrder((long) virtualLinks.size())\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ metric += edge.getMetric();\r
+// delay += edge.getDelay();\r
+ }\r
+\r
+ VirtualPath virtualPath = new VirtualPathBuilder()\r
+ .setPathId(new VirtualPathId(UUID.randomUUID().toString()))\r
+ .setVirtualLink(virtualLinks)\r
+ .setMetric(metric)\r
+ .setBandwidth(0L)\r
+ .setDelay(delay)\r
+ .build();\r
+\r
+ return virtualPath;\r
+ }\r
+\r
+ /**\r
+ * Compute a shortest virtual path with the given bandwidth from the\r
+ * given source vertex to target one.\r
+ *\r
+ * @param source The given source virtual node id.\r
+ * @param target The given target virtual node id.\r
+ * @param bandwidth The given bandwidth for the virtual path.\r
+ * @return The virtual path if successful,or null otherwise.\r
+ */\r
+ public VirtualPath computePath(VirtualNodeId source, VirtualNodeId target, long bandwidth) {\r
+ List<Edge> edges = routingAlgorithm.computePath(routingAlgorithm.getVertex(source.getValue()),\r
+ routingAlgorithm.getVertex(target.getValue()), bandwidth);\r
+\r
+ if ( null == edges || edges.isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink> virtualLinks =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(edges.size());\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink virtualLink;\r
+ long metric = 0;\r
+ long delay = 0;\r
+\r
+ for ( Edge edge : edges ) {\r
+ edge.setBandwidth(edge.getBandwidth() - bandwidth);\r
+ routingAlgorithm.updateEdge(edge);\r
+\r
+ virtualLink = new VirtualLinkBuilder()\r
+ .setLinkId(new VirtualLinkId(edge.getId()))\r
+ .setOrder((long)virtualLinks.size())\r
+ .build();\r
+ virtualLinks.add(virtualLink);\r
+\r
+ metric += edge.getMetric();\r
+// delay += edge.getDelay();\r
+ }\r
+\r
+ VirtualPath virtualPath = new VirtualPathBuilder()\r
+ .setPathId(new VirtualPathId(UUID.randomUUID().toString()))\r
+ .setVirtualLink(virtualLinks)\r
+ .setMetric(metric)\r
+ .setBandwidth(bandwidth)\r
+ .setDelay(delay)\r
+ .build();\r
+\r
+ return virtualPath;\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+ if ( null != virtualNodeChangeListenerReg ) {\r
+ virtualNodeChangeListenerReg.close();\r
+ }\r
+\r
+ if ( null != virtualLinkChangeListenerReg ) {\r
+ virtualLinkChangeListenerReg.close();\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Compute the routes between all virtual routers in the virtual\r
+ * network, and store or update them into the data store.\r
+ */\r
+ private void computeRoute() {\r
+ Map<VirtualRouteKey, VirtualPath> routes = new HashMap<VirtualRouteKey, VirtualPath>();\r
+ VirtualPath virtualPath;\r
+\r
+ for ( VirtualNodeId source : virtualRouters ) {\r
+ for ( VirtualNodeId target : virtualRouters ) {\r
+ if ( !source.equals(target) ) {\r
+ virtualPath = computePath(source, target);\r
+\r
+ if ( null == virtualPath ) {\r
+ continue;\r
+ }\r
+\r
+ routes.put(new VirtualRouteKey(source, target), virtualPath);\r
+ }\r
+ }\r
+ }\r
+\r
+ updateRoute(routes);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Compute the routes between all virtual routers in the virtual\r
+ * network, and store them into the virtual network.\r
+ *\r
+ * @param virtualNetwork The virtual network to store the routes.\r
+ */\r
+ private void computeRoute(VirtualNetwork virtualNetwork) {\r
+ List<VirtualRoute> virtualRoutes = virtualNetwork.getVirtualRoutes().getVirtualRoute();\r
+ List<VirtualPath> virtualPaths = virtualNetwork.getVirtualPaths().getVirtualPath();\r
+ VirtualRoute virtualRoute;\r
+ VirtualPath virtualPath;\r
+\r
+ for ( VirtualNodeId source : virtualRouters ) {\r
+ for ( VirtualNodeId target : virtualRouters ) {\r
+ if ( !source.equals(target) ) {\r
+ virtualPath = computePath(source, target);\r
+\r
+ if ( null == virtualPath ) {\r
+ continue;\r
+ }\r
+\r
+ virtualRoute = new VirtualRouteBuilder().setSrcNodeId(source)\r
+ .setDestNodeId(target)\r
+ .setPathId(virtualPath.getPathId())\r
+ .build();\r
+\r
+ virtualPaths.add(virtualPath);\r
+ virtualRoutes.add(virtualRoute);\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * Update the given routes into the data store. If the route\r
+ * already exists, remove it's old virtual path and store the\r
+ * given new one into the data store.\r
+ *\r
+ * @param routes The given routes to be updated.\r
+ */\r
+ private void updateRoute(Map<VirtualRouteKey, VirtualPath> routes) {\r
+ ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();\r
+\r
+ VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(new VirtualNetworkId(userId.getValue()));\r
+ InstanceIdentifier<VirtualRoute> virtualRouteIid;\r
+ InstanceIdentifier<VirtualPath> virtualPathIid;\r
+ Optional<VirtualRoute> result;\r
+ VirtualRoute virtualRoute;\r
+\r
+ for ( Map.Entry<VirtualRouteKey, VirtualPath> route : routes.entrySet() ) {\r
+ virtualRouteIid = InstanceIdentifier.builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .child(VirtualRoutes.class)\r
+ .child(VirtualRoute.class, route.getKey())\r
+ .build();\r
+\r
+ try {\r
+ result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, virtualRouteIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ LOG.error("Can not read the virtual route from the virtual node {} to {}.",\r
+ route.getKey().getSrcNodeId().getValue(), route.getKey().getDestNodeId().getValue());\r
+\r
+ continue;\r
+ }\r
+\r
+ if ( result.isPresent() ) {\r
+ virtualRoute = result.get();\r
+ virtualPathIid = InstanceIdentifier.builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .child(VirtualPaths.class)\r
+ .child(VirtualPath.class, new VirtualPathKey(virtualRoute.getPathId()))\r
+ .build();\r
+ readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, virtualPathIid);\r
+ }\r
+\r
+ virtualPathIid = InstanceIdentifier.builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .child(VirtualPaths.class)\r
+ .child(VirtualPath.class, route.getValue().getKey())\r
+ .build();\r
+ readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, virtualPathIid, route.getValue(), true);\r
+\r
+ virtualRoute = new VirtualRouteBuilder().setSrcNodeId(route.getKey().getSrcNodeId())\r
+ .setDestNodeId(route.getKey().getDestNodeId())\r
+ .setPathId(route.getValue().getPathId())\r
+ .build();\r
+ readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, virtualRouteIid, virtualRoute, true);\r
+ }\r
+\r
+ readWriteTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to virtual nodes being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class VirtualNodeChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+\r
+ if ( null != createdData && !createdData.isEmpty() ) {\r
+ VirtualNode virtualNode;\r
+ Vertex vertex;\r
+\r
+ for ( DataObject dataObject : createdData.values() ) {\r
+ if ( dataObject instanceof VirtualNode ) {\r
+ virtualNode = (VirtualNode)dataObject;\r
+ vertex = new Vertex(virtualNode.getNodeId().getValue());\r
+\r
+ routingAlgorithm.addVertex(vertex);\r
+\r
+ if ( VirtualNode.NodeType.Vrouter == virtualNode.getNodeType() ) {\r
+ virtualRouters.add(virtualNode.getNodeId());\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to virtual links being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class VirtualLinkChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+\r
+ if ( null != createdData && !createdData.isEmpty() ) {\r
+ VirtualLink virtualLink;\r
+ Edge edge;\r
+ boolean needRerouting = false;\r
+\r
+ for ( DataObject dataObject : createdData.values() ) {\r
+ if ( dataObject instanceof VirtualLink ) {\r
+ virtualLink = (VirtualLink)dataObject;\r
+ edge = new Edge(virtualLink.getLinkId().getValue(), virtualLink.getSrcNodeId().getValue(),\r
+ virtualLink.getDestNodeId().getValue(), virtualLink.getMetric(),\r
+ virtualLink.getBandwidth());\r
+\r
+ routingAlgorithm.addEdge(edge);\r
+\r
+ if ( virtualRouters.contains(virtualLink.getSrcNodeId())\r
+ && virtualRouters.contains(virtualLink.getDestNodeId()) ) {\r
+ needRerouting = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( needRerouting ) {\r
+ computeRoute();\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.computation;\r
+\r
+/**\r
+ * An exception in virtual network mapping.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class VNMappingException extends Exception {\r
+ private static final long serialVersionUID = -3854801203901305270L;\r
+\r
+ public VNMappingException() {\r
+ super();\r
+\r
+ return;\r
+ }\r
+\r
+ public VNMappingException(String message) {\r
+ super(message);\r
+\r
+ return;\r
+ }\r
+\r
+ public VNMappingException(Throwable cause) {\r
+ super(cause);\r
+\r
+ return;\r
+ }\r
+\r
+ public VNMappingException(String message, Throwable cause) {\r
+ super(message, cause);\r
+\r
+ return;\r
+ }\r
+\r
+ public VNMappingException(String message, Throwable cause,\r
+ boolean enableSuppression,\r
+ boolean writableStackTrace) {\r
+ super(message, cause, enableSuppression, writableStackTrace);\r
+\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.computation;\r
+\r
+import com.google.common.base.Optional;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNodeAttributeDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalPortAttributeDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.definition.AttributeMatchPatterns;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.attribute.value.RangeValue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalLinks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPathBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.attribute.definitions.PhysicalNodeAttributeDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.attribute.definitions.PhysicalNodeAttributeDefinitionKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.attribute.definitions.PhysicalPortAttributeDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.attribute.definitions.PhysicalPortAttributeDefinitionKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.Attribute;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLinkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.port.instance.PhysicalResourceRequirement;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.PhysicalResourceInstance;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.VirtualResourceInstance;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.user.vn.pn.mapping.VnPnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.user.vn.pn.mapping.VnPnMappingResultBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.*;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.*;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+/**\r
+ * The virtual network mapping unit implements the following functions:\r
+ * (1) Automatically perform the virtual network mapping when the user's\r
+ * virtual network changed, which is subscribed from the data store.\r
+ * (2) Automatically perform the remapping for the virtual networks that\r
+ * are influenced by the changes of the underlying physical network\r
+ * which are also subscribed from the data store.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class VNMappingUnit implements AutoCloseable {\r
+ private static final Logger LOG = LoggerFactory.getLogger(VNMappingUnit.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ /**\r
+ * The physical network computation unit.\r
+ */\r
+ private PNComputationUnit pnComputationUnit;\r
+\r
+ /**\r
+ * The registrations for the physical port change listeners.\r
+ */\r
+ private Map<PhysicalNodeId, Map<PhysicalPortId, ListenerRegistration<DataChangeListener>>> physicalPortChangeListenerRegs;\r
+\r
+ /**\r
+ * The registration for the physical node change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> physicalNodeChangeListenerReg;\r
+\r
+ /**\r
+ * The registration for the physical link change listener.\r
+ */\r
+ private ListenerRegistration<DataChangeListener> physicalLinkChangeListenerReg;\r
+\r
+ public VNMappingUnit(DataBroker dataBroker, PNComputationUnit pnComputationUnit) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+ this.pnComputationUnit = pnComputationUnit;\r
+\r
+ physicalPortChangeListenerRegs =\r
+ new HashMap<PhysicalNodeId, Map<PhysicalPortId, ListenerRegistration<DataChangeListener>>>();\r
+\r
+ InstanceIdentifier<PhysicalNode> physicalNodeIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalNodes.class)\r
+ .child(PhysicalNode.class)\r
+ .build();\r
+ InstanceIdentifier<PhysicalLink> physicalLinkIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalLinks.class)\r
+ .child(PhysicalLink.class)\r
+ .build();\r
+\r
+ physicalNodeChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,\r
+ physicalNodeIid, new PhysicalNodeChangeListener(), DataChangeScope.BASE);\r
+ physicalLinkChangeListenerReg = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,\r
+ physicalLinkIid, new PhysicalLinkChangeListener(), DataChangeScope.BASE);\r
+\r
+ LOG.debug("Initialized the virtual network mapping unit.");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNetwork TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalPaths TODO\r
+ */\r
+ public void virtualNetworkMapping(VirtualNetwork virtualNetwork, UserVnPnMapping userVnPnMapping,\r
+ List<PhysicalPath> physicalPaths)\r
+ throws VNMappingException {\r
+ ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();\r
+\r
+ InstanceIdentifier<PhysicalNodes> physicalNodesIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .child(PhysicalNodes.class)\r
+ .build();\r
+ Optional<PhysicalNodes> result;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, physicalNodesIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new VNMappingException("Can not read the physical nodes.");\r
+ }\r
+\r
+ PhysicalNodes physicalNodes = result.get();\r
+ List<PhysicalNode> physicalNodeList = physicalNodes.getPhysicalNode();\r
+\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ List<VirtualPort> virtualPorts;\r
+ PhysicalNode physicalNode;\r
+ PhysicalPort physicalPort;\r
+ VnPnMappingResult vnPnMappingResult;\r
+\r
+ for ( VirtualNode virtualNode : virtualNodes ) {\r
+ physicalNode = virtualNodeMapping(virtualNetwork.getNetworkId(), virtualNode, physicalNodeList);\r
+\r
+ if ( null == physicalNode ) {\r
+ throw new VNMappingException("Failed mapping for the virtual node " +\r
+ virtualNode.getNodeId().getValue() + " in the virtual network " +\r
+ virtualNetwork.getNetworkId().getValue());\r
+ }\r
+\r
+ virtualPorts = virtualNode.getVirtualPort();\r
+\r
+ for ( VirtualPort virtualPort : virtualPorts ) {\r
+ if ( VirtualPort.PortType.External == virtualPort.getPortType() ) {\r
+ physicalPort = virtualPortMapping(virtualNetwork.getNetworkId(),\r
+ virtualNode.getNodeId(), virtualPort, physicalNode);\r
+\r
+ if ( null == physicalPort ) {\r
+ throw new VNMappingException("Failed mapping for the virtual port " +\r
+ virtualPort.getPortId().getValue() + " of the virtual node " +\r
+ virtualNode.getNodeId().getValue() + " in the virtual network " +\r
+ virtualNetwork.getNetworkId().getValue());\r
+ }\r
+\r
+ vnPnMappingResult = new VnPnMappingResultBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResourceInstance.VirtualResourceType.Vport)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPort.getPortId().getValue()))\r
+ .setParentVirtualResourceEntityId(new VirtualResourceEntityId(virtualNode.getNodeId().getValue()))\r
+ .setPhysicalResourceId(new PhysicalResourceId(UUID.randomUUID().toString()))\r
+ .setPhysicalResourceType(PhysicalResourceInstance.PhysicalResourceType.Port)\r
+ .setPhysicalResourceEntityId(new PhysicalResourceEntityId(physicalPort.getPortId().getValue()))\r
+ .setParentPhysicalResourceEntityId(new PhysicalResourceEntityId(physicalNode.getNodeId().getValue()))\r
+ .build();\r
+\r
+ vnPnMappingResults.add(vnPnMappingResult);\r
+ }\r
+ }\r
+\r
+ vnPnMappingResult = new VnPnMappingResultBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResourceInstance.VirtualResourceType.Vnode)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualNode.getNodeId().getValue()))\r
+ .setPhysicalResourceId(new PhysicalResourceId(UUID.randomUUID().toString()))\r
+ .setPhysicalResourceType(PhysicalResourceInstance.PhysicalResourceType.Node)\r
+ .setPhysicalResourceEntityId(new PhysicalResourceEntityId(physicalNode.getNodeId().getValue()))\r
+ .build();\r
+\r
+ vnPnMappingResults.add(vnPnMappingResult);\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+ List<VirtualLink> newVirtualLinks = new ArrayList<VirtualLink>(virtualLinks.size());\r
+ PhysicalPath physicalPath;\r
+ VirtualLink newVirtualLink;\r
+\r
+ for ( VirtualLink virtualLink : virtualLinks ) {\r
+ physicalPath = virtualLinkMapping(virtualNetwork.getNetworkId(), virtualLink, userVnPnMapping);\r
+\r
+ if ( null == physicalPath ) {\r
+ throw new VNMappingException("Failed mapping for the virtual link " +\r
+ virtualLink.getLinkId().getValue() + " in the virtual network " +\r
+ virtualNetwork.getNetworkId().getValue());\r
+ }\r
+\r
+ physicalPaths.add(physicalPath);\r
+\r
+ newVirtualLink = new VirtualLinkBuilder(virtualLink)\r
+ .setMetric(physicalPath.getMetric())\r
+ .setDelay(physicalPath.getDelay())\r
+ .build();\r
+\r
+ newVirtualLinks.add(newVirtualLink);\r
+\r
+ vnPnMappingResult = new VnPnMappingResultBuilder()\r
+ .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))\r
+ .setVirtualResourceType(VirtualResourceInstance.VirtualResourceType.Vlink)\r
+ .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualLink.getLinkId().getValue()))\r
+ .setPhysicalResourceId(new PhysicalResourceId(UUID.randomUUID().toString()))\r
+ .setPhysicalResourceType(PhysicalResourceInstance.PhysicalResourceType.Path)\r
+ .setPhysicalResourceEntityId(new PhysicalResourceEntityId(physicalPath.getPathId().getValue()))\r
+ .build();\r
+\r
+ vnPnMappingResults.add(vnPnMappingResult);\r
+ }\r
+\r
+ virtualLinks.clear();\r
+ virtualLinks.addAll(newVirtualLinks);\r
+\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+ for ( Map<PhysicalPortId, ListenerRegistration<DataChangeListener>>\r
+ physicalPortChangeListenerRegs1 : physicalPortChangeListenerRegs.values() ) {\r
+ for ( ListenerRegistration<DataChangeListener>\r
+ physicalPortChangeListenerReg : physicalPortChangeListenerRegs1.values() ) {\r
+ if ( null != physicalPortChangeListenerReg ) {\r
+ physicalPortChangeListenerReg.close();\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( null != physicalNodeChangeListenerReg ) {\r
+ physicalNodeChangeListenerReg.close();\r
+ }\r
+\r
+ if ( null != physicalLinkChangeListenerReg ) {\r
+ physicalLinkChangeListenerReg.close();\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNetworkId TODO\r
+ * @param virtualNodeId TODO\r
+ * @param virtualPort TODO\r
+ * @param physicalNode TODO\r
+ * @return TODO\r
+ */\r
+ private PhysicalPort virtualPortMapping(VirtualNetworkId virtualNetworkId, VirtualNodeId virtualNodeId,\r
+ VirtualPort virtualPort, PhysicalNode physicalNode)\r
+ throws VNMappingException {\r
+ if ( VirtualPort.PortType.Internal == virtualPort.getPortType() ) {\r
+ return null;\r
+ }\r
+\r
+ List<PhysicalPort> physicalPorts = physicalNode.getPhysicalPort();\r
+ List<PhysicalResourceRequirement> physicalResourceRequirements = virtualPort.getPhysicalResourceRequirement();\r
+\r
+ for ( PhysicalPort physicalPort : physicalPorts ) {\r
+ if ( PhysicalPort.PortType.External == physicalPort.getPortType()\r
+ && checkPhysicalPortSatisfied(physicalPort, physicalResourceRequirements) ) {\r
+ return physicalPort;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNetworkId TODO\r
+ * @param virtualNode TODO\r
+ * @param physicalNodes TODO\r
+ * @return TODO\r
+ */\r
+ private PhysicalNode virtualNodeMapping(VirtualNetworkId virtualNetworkId, VirtualNode virtualNode,\r
+ List<PhysicalNode> physicalNodes)\r
+ throws VNMappingException {\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>\r
+ physicalResourceRequirements = virtualNode.getPhysicalResourceRequirement();\r
+ List<PhysicalNode> candidates = new LinkedList<PhysicalNode>();\r
+\r
+ switch ( virtualNode.getNodeType() ) {\r
+ case Vswitch:\r
+ for ( PhysicalNode physicalNode : physicalNodes ) {\r
+ if ( PhysicalNode.NodeType.Switch == physicalNode.getNodeType() ) {\r
+ if ( checkPhysicalNodeSatisfied(physicalNode, physicalResourceRequirements) ) {\r
+ candidates.add(physicalNode);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ case Vrouter:\r
+ for ( PhysicalNode physicalNode : physicalNodes ) {\r
+ if ( PhysicalNode.NodeType.Router == physicalNode.getNodeType() ) {\r
+ if ( checkPhysicalNodeSatisfied(physicalNode, physicalResourceRequirements) ) {\r
+ candidates.add(physicalNode);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ case Vfirewall:\r
+ for ( PhysicalNode physicalNode : physicalNodes ) {\r
+ if ( PhysicalNode.NodeType.Firewall == physicalNode.getNodeType() ) {\r
+ if ( checkPhysicalNodeSatisfied(physicalNode, physicalResourceRequirements) ) {\r
+ candidates.add(physicalNode);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ case Vloadbalancer:\r
+ for ( PhysicalNode physicalNode : physicalNodes ) {\r
+ if ( PhysicalNode.NodeType.Loadbalancer == physicalNode.getNodeType() ) {\r
+ if ( checkPhysicalNodeSatisfied(physicalNode, physicalResourceRequirements) ) {\r
+ candidates.add(physicalNode);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported virtual node type " +\r
+ virtualNode.getNodeType() + ".");\r
+// break;\r
+ }\r
+\r
+ if ( candidates.isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ return candidates.get(0);\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param virtualNetworkId TODO\r
+ * @param virtualLink TODO\r
+ * @param userVnPnMapping TODO\r
+ * @return TODO\r
+ */\r
+ private PhysicalPath virtualLinkMapping(VirtualNetworkId virtualNetworkId, VirtualLink virtualLink,\r
+ UserVnPnMapping userVnPnMapping)\r
+ throws VNMappingException {\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+ VnPnMappingResult vnPnMappingResult = VNMappingUnitUtils.getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLink.getSrcNodeId().getValue()));\r
+\r
+ if ( null == vnPnMappingResult ) {\r
+ throw new VNMappingException("Can not get the vn-pn mapping result for " +\r
+ "the virtual node " + virtualLink.getSrcNodeId().getValue());\r
+ }\r
+\r
+ PhysicalNodeId source = new PhysicalNodeId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+\r
+ vnPnMappingResult = VNMappingUnitUtils.getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLink.getDestNodeId().getValue()));\r
+\r
+ if ( null == vnPnMappingResult ) {\r
+ throw new VNMappingException("Can not get the vn-pn mapping result for " +\r
+ "the virtual node " + virtualLink.getDestNodeId().getValue());\r
+ }\r
+\r
+ PhysicalNodeId target = new PhysicalNodeId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+\r
+ if ( source.equals(target) ) {\r
+ PhysicalPath physicalPath = new PhysicalPathBuilder()\r
+ .setPathId(new PhysicalPathId(UUID.randomUUID().toString()))\r
+ .setPhysicalLink(new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>(0))\r
+ .setMetric(0L)\r
+ .setBandwidth(virtualLink.getBandwidth())\r
+ .setDelay(0L)\r
+ .build();\r
+\r
+ return physicalPath;\r
+ }\r
+\r
+ PhysicalPath physicalPath;\r
+\r
+ if ( 0 == virtualLink.getBandwidth() ) {\r
+ physicalPath = pnComputationUnit.computePath(source, target);\r
+ } else {\r
+ physicalPath = pnComputationUnit.computePath(source, target, virtualLink.getBandwidth());\r
+ }\r
+\r
+ return physicalPath;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param physicalPort TODO\r
+ * @param physicalResourceRequirements TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkPhysicalPortSatisfied(PhysicalPort physicalPort,\r
+ List<PhysicalResourceRequirement> physicalResourceRequirements)\r
+ throws VNMappingException {\r
+ List<Attribute> attributes = physicalPort.getAttribute();\r
+ Attribute attribute;\r
+\r
+ for ( PhysicalResourceRequirement physicalResourceRequirement : physicalResourceRequirements ) {\r
+ attribute = getPhysicalPortAttribute(attributes, physicalResourceRequirement.getAttributeName());\r
+\r
+ if ( null == attribute ) {\r
+ return false;\r
+ }\r
+\r
+ if ( !checkPhysicalPortAttributeSatisfied(attribute, physicalResourceRequirement) ) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param physicalNode TODO\r
+ * @param physicalResourceRequirements TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkPhysicalNodeSatisfied(PhysicalNode physicalNode,\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement>\r
+ physicalResourceRequirements)\r
+ throws VNMappingException {\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>\r
+ attributes = physicalNode.getAttribute();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute attribute;\r
+\r
+ for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement\r
+ physicalResourceRequirement : physicalResourceRequirements ) {\r
+ attribute = getPhysicalNodeAttribute(attributes, physicalResourceRequirement.getAttributeName());\r
+\r
+ if ( null == attribute ) {\r
+ return false;\r
+ }\r
+\r
+ if ( !checkPhysicalNodeAttributeSatisfied(attribute, physicalResourceRequirement) ) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributes TODO\r
+ * @param attributeName TODO\r
+ * @return TODO\r
+ */\r
+ private Attribute getPhysicalPortAttribute(List<Attribute> attributes, AttributeName attributeName) {\r
+ for ( Attribute attribute : attributes ) {\r
+ if ( attribute.getAttributeName().equals(attributeName) ) {\r
+ return attribute;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributes TODO\r
+ * @param attributeName TODO\r
+ * @return TODO\r
+ */\r
+ private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute getPhysicalNodeAttribute(\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute> attributes,\r
+ AttributeName attributeName) {\r
+ for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute\r
+ attribute : attributes ) {\r
+ if ( attribute.getAttributeName().equals(attributeName) ) {\r
+ return attribute;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attribute TODO\r
+ * @param physicalResourceRequirement TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkPhysicalPortAttributeSatisfied(Attribute attribute,\r
+ PhysicalResourceRequirement physicalResourceRequirement)\r
+ throws VNMappingException {\r
+ ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();\r
+\r
+ InstanceIdentifier<PhysicalPortAttributeDefinition> physicalPortAttributeDefinitionIid = InstanceIdentifier\r
+ .builder(PhysicalPortAttributeDefinitions.class)\r
+ .child(PhysicalPortAttributeDefinition.class,\r
+ new PhysicalPortAttributeDefinitionKey(attribute.getAttributeName()))\r
+ .build();\r
+ Optional<PhysicalPortAttributeDefinition> result;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION,\r
+ physicalPortAttributeDefinitionIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new VNMappingException("Can not read the physical port attribute definition " +\r
+ "with attribute name " + attribute.getAttributeName().getValue() + ".");\r
+ }\r
+\r
+ if ( !result.isPresent() ) {\r
+ throw new VNMappingException("The physical port attribute definition with attribute name " +\r
+ attribute.getAttributeName().getValue() + " does not exist.");\r
+ }\r
+\r
+ PhysicalPortAttributeDefinition physicalPortAttributeDefinition = result.get();\r
+ List<AttributeMatchPatterns.AttributeMatchPattern> attributeMatchPatterns\r
+ = physicalPortAttributeDefinition.getAttributeMatchPatterns().getAttributeMatchPattern();\r
+ PhysicalResourceRequirement.AttributeMatchPattern attributeMatchPattern\r
+ = physicalResourceRequirement.getAttributeMatchPattern();\r
+\r
+ if ( !checkAttributeMatchPatternSpecified(attributeMatchPatterns, attributeMatchPattern) ) {\r
+ throw new VNMappingException("The attribute match pattern " + attributeMatchPattern +\r
+ " is not specified in the physical port attribute definition " +\r
+ "with attribute name " + attribute.getAttributeName().getValue() + ".");\r
+ }\r
+\r
+ switch ( physicalPortAttributeDefinition.getAttributeValueType() ) {\r
+ case String:\r
+ return checkAttributeStringValueSatisfied(attribute.getAttributeValue().getStringValue(),\r
+ physicalResourceRequirement.getAttributeValue().getStringValue(), attributeMatchPattern);\r
+\r
+ case Int:\r
+ return checkAttributeIntegerValueSatisfied(attribute.getAttributeValue().getIntValue(),\r
+ physicalResourceRequirement.getAttributeValue().getIntValue(), attributeMatchPattern);\r
+\r
+ case Range:\r
+ return checkAttributeRangeValueSatisfied(attribute.getAttributeValue().getIntValue(),\r
+ physicalResourceRequirement.getAttributeValue().getRangeValue(), attributeMatchPattern);\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported physical port attribute value type " +\r
+ physicalPortAttributeDefinition.getAttributeValueType() + ".");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attribute TODO\r
+ * @param physicalResourceRequirement TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkPhysicalNodeAttributeSatisfied(\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute attribute,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement physicalResourceRequirement)\r
+ throws VNMappingException {\r
+ ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();\r
+\r
+ InstanceIdentifier<PhysicalNodeAttributeDefinition> physicalNodeAttributeDefinitionIid = InstanceIdentifier\r
+ .builder(PhysicalNodeAttributeDefinitions.class)\r
+ .child(PhysicalNodeAttributeDefinition.class,\r
+ new PhysicalNodeAttributeDefinitionKey(attribute.getAttributeName()))\r
+ .build();\r
+ Optional<PhysicalNodeAttributeDefinition> result;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION,\r
+ physicalNodeAttributeDefinitionIid).get();\r
+ } catch ( InterruptedException | ExecutionException exception ) {\r
+ throw new VNMappingException("Can not read the physical node attribute definition " +\r
+ "with attribute name " + attribute.getAttributeName().getValue() + ".");\r
+ }\r
+\r
+ if ( !result.isPresent() ) {\r
+ throw new VNMappingException("The physical node attribute definition with attribute name " +\r
+ attribute.getAttributeName().getValue() + " does not exist.");\r
+ }\r
+\r
+ PhysicalNodeAttributeDefinition physicalNodeAttributeDefinition = result.get();\r
+ List<AttributeMatchPatterns.AttributeMatchPattern> attributeMatchPatterns\r
+ = physicalNodeAttributeDefinition.getAttributeMatchPatterns().getAttributeMatchPattern();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern\r
+ attributeMatchPattern = physicalResourceRequirement.getAttributeMatchPattern();\r
+\r
+ if ( !checkAttributeMatchPatternSpecified(attributeMatchPatterns, attributeMatchPattern) ) {\r
+ throw new VNMappingException("The attribute match pattern " + attributeMatchPattern +\r
+ " is not specified in the physical node attribute definition " +\r
+ "with attribute name " + attribute.getAttributeName().getValue() + ".");\r
+ }\r
+\r
+ switch ( physicalNodeAttributeDefinition.getAttributeValueType() ) {\r
+ case String:\r
+ return checkAttributeStringValueSatisfied(attribute.getAttributeValue().getStringValue(),\r
+ physicalResourceRequirement.getAttributeValue().getStringValue(), attributeMatchPattern);\r
+\r
+ case Int:\r
+ return checkAttributeIntegerValueSatisfied(attribute.getAttributeValue().getIntValue(),\r
+ physicalResourceRequirement.getAttributeValue().getIntValue(), attributeMatchPattern);\r
+\r
+ case Range:\r
+ return checkAttributeRangeValueSatisfied(attribute.getAttributeValue().getIntValue(),\r
+ physicalResourceRequirement.getAttributeValue().getRangeValue(), attributeMatchPattern);\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported physical node attribute value type " +\r
+ physicalNodeAttributeDefinition.getAttributeValueType() + ".");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeMatchPatterns TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeMatchPatternSpecified(List<AttributeMatchPatterns.AttributeMatchPattern> attributeMatchPatterns,\r
+ PhysicalResourceRequirement.AttributeMatchPattern attributeMatchPattern) {\r
+ for ( AttributeMatchPatterns.AttributeMatchPattern attributeMatchPattern1 : attributeMatchPatterns ) {\r
+ if ( attributeMatchPattern1.name().equals(attributeMatchPattern.name()) ) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeMatchPatterns TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeMatchPatternSpecified(List<AttributeMatchPatterns.AttributeMatchPattern> attributeMatchPatterns,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern\r
+ attributeMatchPattern) {\r
+ for ( AttributeMatchPatterns.AttributeMatchPattern attributeMatchPattern1 : attributeMatchPatterns ) {\r
+ if ( attributeMatchPattern1.name().equals(attributeMatchPattern.name()) ) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeValue TODO\r
+ * @param requiredAttributeValue TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeStringValueSatisfied(String attributeValue, String requiredAttributeValue,\r
+ PhysicalResourceRequirement.AttributeMatchPattern attributeMatchPattern)\r
+ throws VNMappingException {\r
+ int result = attributeValue.compareTo(requiredAttributeValue);\r
+\r
+ switch ( attributeMatchPattern ) {\r
+ case LessThan:\r
+ return 0 > result;\r
+\r
+ case NotLessThan:\r
+ return 0 <= result;\r
+\r
+ case Equal:\r
+ return 0 == result;\r
+\r
+ case NotEqual:\r
+ return 0 != result;\r
+\r
+ case GreaterThan:\r
+ return 0 < result;\r
+\r
+ case NotGreaterThan:\r
+ return 0 >= result;\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported attribute match pattern " +\r
+ attributeMatchPattern + " for the attribute string value.");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeValue TODO\r
+ * @param requiredAttributeValue TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeStringValueSatisfied(String attributeValue, String requiredAttributeValue,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern\r
+ attributeMatchPattern)\r
+ throws VNMappingException {\r
+ int result = attributeValue.compareTo(requiredAttributeValue);\r
+\r
+ switch ( attributeMatchPattern ) {\r
+ case LessThan:\r
+ return 0 > result;\r
+\r
+ case NotLessThan:\r
+ return 0 <= result;\r
+\r
+ case Equal:\r
+ return 0 == result;\r
+\r
+ case NotEqual:\r
+ return 0 != result;\r
+\r
+ case GreaterThan:\r
+ return 0 < result;\r
+\r
+ case NotGreaterThan:\r
+ return 0 >= result;\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported attribute match pattern " +\r
+ attributeMatchPattern + " for the attribute string value.");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeValue TODO\r
+ * @param requiredAttributeValue TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeIntegerValueSatisfied(Long attributeValue, Long requiredAttributeValue,\r
+ PhysicalResourceRequirement.AttributeMatchPattern attributeMatchPattern)\r
+ throws VNMappingException {\r
+ int result = attributeValue.compareTo(requiredAttributeValue);\r
+\r
+ switch ( attributeMatchPattern ) {\r
+ case LessThan:\r
+ return 0 > result;\r
+\r
+ case NotLessThan:\r
+ return 0 <= result;\r
+\r
+ case Equal:\r
+ return 0 == result;\r
+\r
+ case NotEqual:\r
+ return 0 != result;\r
+\r
+ case GreaterThan:\r
+ return 0 < result;\r
+\r
+ case NotGreaterThan:\r
+ return 0 >= result;\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported attribute match pattern " +\r
+ attributeMatchPattern + " for the attribute integer value.");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeValue TODO\r
+ * @param requiredAttributeValue TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeIntegerValueSatisfied(Long attributeValue, Long requiredAttributeValue,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern\r
+ attributeMatchPattern)\r
+ throws VNMappingException {\r
+ int result = attributeValue.compareTo(requiredAttributeValue);\r
+\r
+ switch ( attributeMatchPattern ) {\r
+ case LessThan:\r
+ return 0 > result;\r
+\r
+ case NotLessThan:\r
+ return 0 <= result;\r
+\r
+ case Equal:\r
+ return 0 == result;\r
+\r
+ case NotEqual:\r
+ return 0 != result;\r
+\r
+ case GreaterThan:\r
+ return 0 < result;\r
+\r
+ case NotGreaterThan:\r
+ return 0 >= result;\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported attribute match pattern " +\r
+ attributeMatchPattern + " for the attribute integer value.");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeValue TODO\r
+ * @param requiredAttributeValue TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeRangeValueSatisfied(Long attributeValue, RangeValue requiredAttributeValue,\r
+ PhysicalResourceRequirement.AttributeMatchPattern attributeMatchPattern)\r
+ throws VNMappingException {\r
+ switch ( attributeMatchPattern ) {\r
+ case Between:\r
+ return attributeValue > requiredAttributeValue.getMin()\r
+ && attributeValue < requiredAttributeValue.getMax();\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported attribute match pattern " +\r
+ attributeMatchPattern + " for the attribute range value.");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param attributeValue TODO\r
+ * @param requiredAttributeValue TODO\r
+ * @param attributeMatchPattern TODO\r
+ * @return TODO\r
+ */\r
+ private boolean checkAttributeRangeValueSatisfied(Long attributeValue, RangeValue requiredAttributeValue,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.PhysicalResourceRequirement.AttributeMatchPattern\r
+ attributeMatchPattern)\r
+ throws VNMappingException {\r
+ switch ( attributeMatchPattern ) {\r
+ case Between:\r
+ return attributeValue > requiredAttributeValue.getMin()\r
+ && attributeValue < requiredAttributeValue.getMax();\r
+\r
+ default:\r
+ throw new VNMappingException("Unsupported attribute match pattern " +\r
+ attributeMatchPattern + " for the attribute range value.");\r
+// break;\r
+ }\r
+\r
+// return false;\r
+ }\r
+\r
+// /**\r
+// * A listener to change events related to virtual ports being\r
+// * added, removed or updated.\r
+// *\r
+// * @author Zhigang Ji\r
+// */\r
+// private class VirtualPortChangeListener implements DataChangeListener {\r
+// /**\r
+// * The virtual network that the virtual port belongs to.\r
+// */\r
+// private VirtualNetworkId virtualNetworkId;\r
+//\r
+// /**\r
+// * The virtual node that the virtual port belongs to.\r
+// */\r
+// private VirtualNodeId virtualNodeId;\r
+//\r
+// public VirtualPortChangeListener(VirtualNetworkId virtualNetworkId, VirtualNodeId virtualNodeId) {\r
+// super();\r
+//\r
+// this.virtualNetworkId = virtualNetworkId;\r
+// this.virtualNodeId = virtualNodeId;\r
+//\r
+// return;\r
+// }\r
+//\r
+// @Override\r
+// public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+// if ( null == change ) {\r
+// return;\r
+// }\r
+//\r
+// Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+//\r
+// if ( null != createdData && !createdData.isEmpty() ) {\r
+// for ( DataObject dataObject : createdData.values() ) {\r
+// if ( dataObject instanceof VirtualPort ) {\r
+// // TODO: 1、执行端口映射。\r
+// }\r
+// }\r
+// }\r
+// }\r
+// }\r
+//\r
+// /**\r
+// * A listener to change events related to virtual nodes being\r
+// * added, removed or updated.\r
+// *\r
+// * @author Zhigang Ji\r
+// */\r
+// private class VirtualNodeChangeListener implements DataChangeListener {\r
+// /**\r
+// * The virtual network that the virtual node belongs to.\r
+// */\r
+// private VirtualNetworkId virtualNetworkId;\r
+//\r
+// public VirtualNodeChangeListener(VirtualNetworkId virtualNetworkId) {\r
+// super();\r
+//\r
+// this.virtualNetworkId = virtualNetworkId;\r
+//\r
+// return;\r
+// }\r
+//\r
+// @Override\r
+// public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+// if ( null == change ) {\r
+// return;\r
+// }\r
+//\r
+// Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+//\r
+// if ( null != createdData && !createdData.isEmpty() ) {\r
+// for ( DataObject dataObject : createdData.values() ) {\r
+// if ( dataObject instanceof VirtualNode ) {\r
+// // TODO: 1、执行节点映射。\r
+// // TODO: 2、启动vports监听(external端口),还需监听vnode中vport的增加。\r
+// // TODO: 3、读取已有vports,并执行端口映射(external端口)。\r
+// }\r
+// }\r
+// }\r
+// }\r
+// }\r
+//\r
+// /**\r
+// * A listener to change events related to virtual links being\r
+// * added, removed or updated.\r
+// *\r
+// * @author Zhigang Ji\r
+// */\r
+// private class VirtualLinkChangeListener implements DataChangeListener {\r
+// /**\r
+// * The virtual network that the virtual link belongs to.\r
+// */\r
+// private VirtualNetworkId virtualNetworkId;\r
+//\r
+// public VirtualLinkChangeListener(VirtualNetworkId virtualNetworkId) {\r
+// super();\r
+//\r
+// this.virtualNetworkId = virtualNetworkId;\r
+//\r
+// return;\r
+// }\r
+//\r
+// @Override\r
+// public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+// if ( null == change ) {\r
+// return;\r
+// }\r
+//\r
+// Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+//\r
+// if ( null != createdData && !createdData.isEmpty() ) {\r
+// for ( DataObject dataObject : createdData.values() ) {\r
+// if ( dataObject instanceof VirtualLink ) {\r
+// // TODO: 1、执行链路映射(两端vport映射结果可不写)。\r
+// }\r
+// }\r
+// }\r
+// }\r
+// }\r
+\r
+ /**\r
+ * A listener to change events related to physical ports being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalPortChangeListener implements DataChangeListener {\r
+ /**\r
+ * The physical node that the physical port belongs to.\r
+ */\r
+ private PhysicalNodeId physicalNodeId;\r
+\r
+ public PhysicalPortChangeListener(PhysicalNodeId physicalNodeId) {\r
+ super();\r
+\r
+ this.physicalNodeId = physicalNodeId;\r
+\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();\r
+\r
+ if ( null != updatedData && !updatedData.isEmpty() ) {\r
+ for ( DataObject dataObject : updatedData.values() ) {\r
+ // TODO\r
+ }\r
+ }\r
+\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+\r
+ // TODO\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to physical nodes being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalNodeChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();\r
+\r
+ if ( null != updatedData && !updatedData.isEmpty() ) {\r
+ for ( DataObject dataObject : updatedData.values() ) {\r
+ // TODO\r
+ }\r
+ }\r
+\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+\r
+ // TODO\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * A listener to change events related to physical links being\r
+ * added, removed or updated.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalLinkChangeListener implements DataChangeListener {\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();\r
+\r
+ if ( null != updatedData && !updatedData.isEmpty() ) {\r
+ for ( DataObject dataObject : updatedData.values() ) {\r
+ // TODO\r
+ }\r
+ }\r
+\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+\r
+ // TODO\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.intent.computation;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.user.vn.pn.mapping.VnPnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualResourceEntityId;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Implement the utilities used in the virtual\r
+ * network mapping.\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+public class VNMappingUnitUtils {\r
+ /**\r
+ * TODO\r
+ *\r
+ * @param vnPnMappingResults TODO\r
+ * @param virtualResourceEntityId TODO\r
+ * @return TODO\r
+ */\r
+ protected static VnPnMappingResult getVnPnMappingResult(List<VnPnMappingResult> vnPnMappingResults,\r
+ VirtualResourceEntityId virtualResourceEntityId) {\r
+ for ( VnPnMappingResult vnPnMappingResult : vnPnMappingResults ) {\r
+ if ( vnPnMappingResult.getVirtualResourceEntityId().equals(virtualResourceEntityId) ) {\r
+ return vnPnMappingResult;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user;\r
+\r
+import com.google.common.util.concurrent.Futures;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;\r
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;\r
+import org.opendaylight.nemo.intent.IntentResolutionException;\r
+import org.opendaylight.nemo.intent.IntentResolver;\r
+import org.opendaylight.nemo.intent.computation.VNMappingException;\r
+import org.opendaylight.nemo.user.advancedquery.AdvancedQuery;\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.nemo.user.tenantmanager.RegisterUser;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.nemo.user.transactionmanager.TransactionBegin;\r
+import org.opendaylight.nemo.user.transactionmanager.TransactionEnd;\r
+import org.opendaylight.nemo.user.vnspacemanager.languagestyle.LanguageIntent;\r
+import org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent.DeleteIntent;\r
+import org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent.UpdateIntent;\r
+import org.opendaylight.nemo.user.vnspacemanager.VNSpaceManagement;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.*;\r
+import org.opendaylight.yangtools.yang.common.RpcResult;\r
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
+\r
+import java.util.concurrent.Future;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/7.\r
+ */\r
+public class UserManager implements NemoIntentService, AutoCloseable {\r
+\r
+ private DataBroker dataBroker;\r
+ private RpcProviderRegistry rpcProviderRegistry;\r
+\r
+ private VNSpaceManagement vnSpaceManagement;\r
+ private RegisterUser registerUser;\r
+ private UpdateIntent updateIntent;\r
+ private DeleteIntent deleteIntent;\r
+ private LanguageIntent languageIntent;\r
+ private TenantManage tenantManage;\r
+ private AAA aaa;\r
+ private TransactionBegin transactionBegin;\r
+ private TransactionEnd transactionEnd;\r
+ private AdvancedQuery advancedQuery;\r
+ private IntentResolver intentResolver;\r
+\r
+ Boolean transaction;\r
+ Boolean informresolver;\r
+\r
+ private RpcRegistration<NemoIntentService> rpcRegistration;\r
+\r
+ public UserManager(DataBroker dataBroker, RpcProviderRegistry rpcProviderRegistry,\r
+ IntentResolver intentResolver)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.rpcProviderRegistry = rpcProviderRegistry;\r
+\r
+ this.intentResolver = intentResolver;\r
+ vnSpaceManagement = new VNSpaceManagement(dataBroker);\r
+ tenantManage = new TenantManage(dataBroker);\r
+ aaa = new AAA(tenantManage);\r
+ registerUser = new RegisterUser(tenantManage);\r
+ updateIntent = new UpdateIntent(dataBroker,tenantManage);\r
+ deleteIntent = new DeleteIntent(dataBroker, tenantManage);\r
+ languageIntent = new LanguageIntent(dataBroker);\r
+ advancedQuery = new AdvancedQuery(dataBroker, tenantManage);\r
+\r
+ transactionBegin = new TransactionBegin();\r
+ transactionEnd = new TransactionEnd();\r
+\r
+ transaction = false;\r
+ informresolver = false;\r
+\r
+ rpcRegistration = rpcProviderRegistry.addRpcImplementation(NemoIntentService.class, this);\r
+ }\r
+ @Override\r
+ public Future<RpcResult<AdvancedNemoQueryOutput>> advancedNemoQuery(AdvancedNemoQueryInput input) {\r
+ RpcResult<AdvancedNemoQueryOutput> advancedNemoQueryOutputRpcResult = null;\r
+ AdvancedNemoQueryOutputBuilder advancedNemoQueryOutputBuilder = new AdvancedNemoQueryOutputBuilder();\r
+\r
+ String errorInfo = advancedQuery.advancedQuery(aaa, input);\r
+ if (errorInfo != null)\r
+ {\r
+ advancedNemoQueryOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(errorInfo);\r
+ }\r
+ else\r
+ {\r
+ advancedNemoQueryOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage(advancedQuery.getAdvancedQueryReuslt(input));\r
+ }\r
+ advancedNemoQueryOutputRpcResult = RpcResultBuilder.<AdvancedNemoQueryOutput>success(advancedNemoQueryOutputBuilder.build()).build();\r
+\r
+ return Futures.immediateFuture(advancedNemoQueryOutputRpcResult);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<BeginTransactionOutput>> beginTransaction(BeginTransactionInput input) {\r
+ RpcResult<BeginTransactionOutput> beginTransactionOutputResult = null;\r
+ BeginTransactionOutputBuilder beginTransactionOutputBuilder = new BeginTransactionOutputBuilder();\r
+\r
+ if (transaction)\r
+ {\r
+ beginTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage("The previous transaction has not been finished.");\r
+ }\r
+ else\r
+ {\r
+ String errorInfo = transactionBegin.transactionbegin(aaa,input);\r
+ if (errorInfo != null)\r
+ {\r
+ beginTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(errorInfo);\r
+ }\r
+ else\r
+ {\r
+ transaction = true;\r
+ beginTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("Transaction Begin.");\r
+ }\r
+ }\r
+ beginTransactionOutputResult = RpcResultBuilder.<BeginTransactionOutput>success(beginTransactionOutputBuilder.build()).build();\r
+ return Futures.immediateFuture(beginTransactionOutputResult);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<EndTransactionOutput>> endTransaction(EndTransactionInput input) {\r
+ RpcResult<EndTransactionOutput> endTransactionOutputResult = null;\r
+ EndTransactionOutputBuilder endTransactionOutputBuilder = new EndTransactionOutputBuilder();\r
+\r
+ if (!transaction)\r
+ {\r
+ endTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage("The transaction has not started.");\r
+ }\r
+ else\r
+ {\r
+ String errorInfo = transactionEnd.transactionend(aaa,input);\r
+ if (errorInfo != null)\r
+ {\r
+ endTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(errorInfo);\r
+ }\r
+ else\r
+ {\r
+ transaction = false;\r
+ if (informresolver)\r
+ {\r
+ informresolver = false;\r
+ try\r
+ {\r
+ intentResolver.resolveIntent(input.getUserId());\r
+ endTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("The transaction ends.");\r
+ }\r
+ catch (IntentResolutionException | VNMappingException e)\r
+ {\r
+ e.printStackTrace();\r
+ endTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(e.getMessage());\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ endTransactionOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("The transaction ends.");\r
+ }\r
+\r
+ }\r
+ }\r
+ endTransactionOutputResult = RpcResultBuilder.<EndTransactionOutput>success(endTransactionOutputBuilder.build()).build();\r
+ return Futures.immediateFuture(endTransactionOutputResult);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<LanguageStyleNemoRequestOutput>> languageStyleNemoRequest(LanguageStyleNemoRequestInput input) {\r
+ RpcResult<LanguageStyleNemoRequestOutput> styleNemoRequestOutputRpcResult = null;\r
+ LanguageStyleNemoRequestOutputBuilder languageStyleNemoRequestOutputBuilder = new LanguageStyleNemoRequestOutputBuilder();\r
+\r
+ String errorInfo = languageIntent.LanIntentHandler(aaa,input);\r
+\r
+ if (errorInfo != null)\r
+ {\r
+ languageStyleNemoRequestOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(errorInfo);\r
+ }\r
+ else\r
+ {\r
+ languageStyleNemoRequestOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("The intent has been stored in this transaction.");\r
+ informresolver = true;\r
+ }\r
+ styleNemoRequestOutputRpcResult = RpcResultBuilder.<LanguageStyleNemoRequestOutput>success(languageStyleNemoRequestOutputBuilder.build()).build();\r
+\r
+ return Futures.immediateFuture(styleNemoRequestOutputRpcResult);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<RegisterUserOutput>> registerUser(RegisterUserInput input) {\r
+ RpcResult<RegisterUserOutput> registerUserOutputRpcResult = null;\r
+ RegisterUserOutputBuilder registerUserOutputBuilder = new RegisterUserOutputBuilder();\r
+ String errorInfo = registerUser.registerUser(input);\r
+\r
+ if (errorInfo != null)\r
+ {\r
+ registerUserOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(errorInfo);\r
+ }\r
+ else\r
+ {\r
+ registerUserOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("Register user successfully.");\r
+ }\r
+\r
+ registerUserOutputRpcResult = RpcResultBuilder.<RegisterUserOutput>success(registerUserOutputBuilder.build()).build();\r
+\r
+ return Futures.immediateFuture(registerUserOutputRpcResult);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<StructureStyleNemoDeleteOutput>> structureStyleNemoDelete(StructureStyleNemoDeleteInput input) {\r
+ RpcResult<StructureStyleNemoDeleteOutput> styleNemoDeleteOutputRpcResult = null;\r
+ StructureStyleNemoDeleteOutputBuilder styleNemoDeleteOutputBuilder = new StructureStyleNemoDeleteOutputBuilder();\r
+\r
+ String errorInfo = deleteIntent.styleNemoDeleteOutput(aaa,input);\r
+\r
+ if (errorInfo != null)\r
+ {\r
+ styleNemoDeleteOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(errorInfo);\r
+ }\r
+ else\r
+ {\r
+ styleNemoDeleteOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("The intent has been handled by user manager successfully.");\r
+ informresolver = true;\r
+ }\r
+\r
+\r
+ styleNemoDeleteOutputRpcResult = RpcResultBuilder.<StructureStyleNemoDeleteOutput>success(styleNemoDeleteOutputBuilder.build()).build();\r
+\r
+ return Futures.immediateFuture(styleNemoDeleteOutputRpcResult);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<StructureStyleNemoUpdateOutput>> structureStyleNemoUpdate(StructureStyleNemoUpdateInput input) {\r
+ RpcResult<StructureStyleNemoUpdateOutput> styleNemoUpdateOutputRpcResult = null;\r
+ StructureStyleNemoUpdateOutputBuilder styleNemoUpdateOutputBuilder = new StructureStyleNemoUpdateOutputBuilder();\r
+\r
+ String erroInfo = updateIntent.updateIntent(aaa,input);\r
+\r
+ if (erroInfo != null)\r
+ {\r
+ styleNemoUpdateOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Error).setMessage(erroInfo);\r
+ }\r
+ else\r
+ {\r
+ styleNemoUpdateOutputBuilder.setResultCode(CommonRpcResult.ResultCode.Ok).setMessage("The intent has been handled by user manager successfully.");\r
+ informresolver = true;\r
+ }\r
+\r
+ styleNemoUpdateOutputRpcResult = RpcResultBuilder.<StructureStyleNemoUpdateOutput>success(styleNemoUpdateOutputBuilder.build()).build();\r
+\r
+ return Futures.immediateFuture(styleNemoUpdateOutputRpcResult);\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+ if ( null != rpcRegistration ) {\r
+ rpcRegistration.close();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.advancedquery;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.AdvancedNemoQueryInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.advanced.nemo.query.input.QueryCondition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Operations;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Results;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.flow.instance.MatchItem;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.flow.instance.Property;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.instance.property.values.IntValue;\r
+import com.google.common.base.Optional;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/29.\r
+ */\r
+public class AdvancedQuery\r
+{\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private QueryDefinitionCheck queryDefinitionCheck;\r
+ private Objects objects;\r
+ private Operations operations;\r
+ private List<Results> resultsList;\r
+ private static final Logger LOG = LoggerFactory.getLogger(QueryDefinitionCheck.class);\r
+\r
+ public AdvancedQuery(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ queryDefinitionCheck = new QueryDefinitionCheck(dataBroker);\r
+ objects = null;\r
+ operations = null;\r
+ resultsList = null;\r
+ }\r
+\r
+ public String advancedQuery(AAA aaa, AdvancedNemoQueryInput input)\r
+ {\r
+ String errorInfo = null;\r
+ List<QueryCondition> queryConditionList = null;\r
+\r
+ errorInfo = aaa.CheckUser(input.getUserId(),input.getUserName(),input.getUserPassword(),input.getUserRole());\r
+\r
+ if (errorInfo != null)\r
+ {\r
+ return errorInfo;\r
+ }\r
+ else\r
+ {\r
+ if (input.getQueryCondition() != null)\r
+ {\r
+ queryConditionList = input.getQueryCondition();\r
+ for (QueryCondition queryCondition : queryConditionList)\r
+ {\r
+ errorInfo = queryDefinitionCheck.CheckQueryDefinition(queryCondition);\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ public String getAdvancedQueryReuslt(AdvancedNemoQueryInput advancedNemoQueryInput)\r
+ {\r
+ UserId userId = advancedNemoQueryInput.getUserId();\r
+ List<QueryCondition> queryConditionList = advancedNemoQueryInput.getQueryCondition();\r
+ String queryResult = null;\r
+\r
+ for (QueryCondition queryCondition : queryConditionList)\r
+ {\r
+ if (queryCondition.getQueryIntentType() != null)\r
+ {\r
+ if (queryCondition.getQueryIntentType().getIntValue() == 0)\r
+ {\r
+ queryResult += nodeInstanceQuery(userId, queryCondition);\r
+ }\r
+ if (queryCondition.getQueryIntentType().getIntValue() == 1)\r
+ {\r
+ queryResult += connectionInstanceQuery(userId,queryCondition);\r
+ }\r
+ if (queryCondition.getQueryIntentType().getIntValue() == 2)\r
+ {\r
+ queryResult += flowInstanceQuery(userId,queryCondition);\r
+ }\r
+ if (queryCondition.getQueryIntentType().getIntValue() == 3)\r
+ {\r
+ queryResult += operationsInstanceQuery(userId,queryCondition);\r
+ }\r
+ }\r
+ }\r
+\r
+ return queryResult;\r
+ }\r
+\r
+ private String nodeInstanceQuery(UserId userId, QueryCondition queryCondition)\r
+ {\r
+ String queryResult = null;\r
+\r
+ fetchObjectsInstance(userId);\r
+\r
+ if (objects != null)\r
+ {\r
+ if (objects.getNode() != null)\r
+ {\r
+ List<Node> nodeList = objects.getNode();\r
+\r
+ for (Node node : nodeList)\r
+ {\r
+ if (node.getProperty() != null)\r
+ {\r
+ for(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.Property property : node.getProperty())\r
+ {\r
+ if (property.getPropertyName().equals(queryCondition.getQueryConditionName()))\r
+ {\r
+ int operator = queryCondition.getQueryConditionMatchPattern().getIntValue();\r
+ List<IntValue> values =property.getPropertyValues().getIntValue();\r
+ if (operator == 0 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()<queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += node.getNodeId().toString()+node.getNodeName().toString()+node.getNodeType().toString()+node.getSubNode().toString()+node.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 1 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()<=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += node.getNodeId().toString()+node.getNodeName().toString()+node.getNodeType().toString()+node.getSubNode().toString()+node.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 2 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()==queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += node.getNodeId().toString()+node.getNodeName().toString()+node.getNodeType().toString()+node.getSubNode().toString()+node.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 3 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()!=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += node.getNodeId().toString()+node.getNodeName().toString()+node.getNodeType().toString()+node.getSubNode().toString()+node.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 4 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()>queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += node.getNodeId().toString()+node.getNodeName().toString()+node.getNodeType().toString()+node.getSubNode().toString()+node.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 5 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()>=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += node.getNodeId().toString()+node.getNodeName().toString()+node.getNodeType().toString()+node.getSubNode().toString()+node.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 6 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ //between todo\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ return queryResult;\r
+ }\r
+\r
+ private String connectionInstanceQuery(UserId userId, QueryCondition queryCondition)\r
+ {\r
+ String queryResult = null;\r
+\r
+ fetchObjectsInstance(userId);\r
+ if (objects != null)\r
+ {\r
+ if (objects.getConnection() != null)\r
+ {\r
+ List<Connection> connectionList = objects.getConnection();\r
+\r
+ for (Connection connection : connectionList)\r
+ {\r
+ if (connection.getProperty() != null)\r
+ {\r
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property property : connection.getProperty())\r
+ {\r
+ if (property.getPropertyName().equals(queryCondition.getQueryConditionName()))\r
+ {\r
+ int operator = queryCondition.getQueryConditionMatchPattern().getIntValue();\r
+ List<IntValue> values =property.getPropertyValues().getIntValue();\r
+ if (operator == 0 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()<queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += connection.getConnectionId().toString()+ connection.getConnectionName().toString()+connection.getConnectionType().toString()+connection.getEndNode().toString()+connection.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 1 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()<=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += connection.getConnectionId().toString()+ connection.getConnectionName().toString()+connection.getConnectionType().toString()+connection.getEndNode().toString()+connection.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 2 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()==queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += connection.getConnectionId().toString()+ connection.getConnectionName().toString()+connection.getConnectionType().toString()+connection.getEndNode().toString()+connection.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 3 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()!=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += connection.getConnectionId().toString()+ connection.getConnectionName().toString()+connection.getConnectionType().toString()+connection.getEndNode().toString()+connection.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 4 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()>queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += connection.getConnectionId().toString()+ connection.getConnectionName().toString()+connection.getConnectionType().toString()+connection.getEndNode().toString()+connection.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 5 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()>=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += connection.getConnectionId().toString()+ connection.getConnectionName().toString()+connection.getConnectionType().toString()+connection.getEndNode().toString()+connection.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 6 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ //between todo\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ return queryResult;\r
+ }\r
+\r
+ private String flowInstanceQuery(UserId userId, QueryCondition queryCondition)\r
+ {\r
+ String queryResult = null;\r
+\r
+ fetchObjectsInstance(userId);\r
+ if (objects != null)\r
+ {\r
+ if (objects.getFlow() != null)\r
+ {\r
+ List<Flow> flowList = objects.getFlow();\r
+\r
+ for (Flow flow: flowList)\r
+ {\r
+ if (flow.getProperty() != null)\r
+ {\r
+ for (Property property : flow.getProperty())\r
+ {\r
+ if (property.getPropertyName().equals(queryCondition.getQueryConditionName()))\r
+ {\r
+ int operator = queryCondition.getQueryConditionMatchPattern().getIntValue();\r
+ List<IntValue> values = property.getPropertyValues().getIntValue();\r
+ if (operator == 0 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()<queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 1 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()<=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 2 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()==queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 3 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()!=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 4 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()>queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 5 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ for(IntValue value:values)\r
+ {\r
+ if (value.getValue()>=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ }\r
+ }\r
+ if (operator == 6 && (property.getPropertyValues().getIntValue() != null))\r
+ {\r
+ //between todo\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (flow.getMatchItem() != null)\r
+ {\r
+ for(MatchItem matchItem: flow.getMatchItem())\r
+ {\r
+ if (matchItem.getMatchItemName().equals(queryCondition.getQueryConditionName()))\r
+ {\r
+ int operator = queryCondition.getQueryConditionMatchPattern().getIntValue();\r
+ if (operator == 0 && matchItem.getMatchItemValue().getIntValue()<queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ if (operator == 1 && matchItem.getMatchItemValue().getIntValue()<=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ if (operator == 2 && matchItem.getMatchItemValue().getIntValue()==queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ if (operator == 3 && matchItem.getMatchItemValue().getIntValue()!=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ if (operator == 4 && matchItem.getMatchItemValue().getIntValue()>queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ if (operator == 5 && matchItem.getMatchItemValue().getIntValue()>=queryCondition.getQueryConditionTargetValue().getIntValue())\r
+ {\r
+ queryResult += flow.getFlowId().toString() + flow.getFlowName().toString() + flow.getMatchItem().toString() + flow.getProperty().toString();\r
+ }\r
+ if (operator == 6 )\r
+ {\r
+ //todo\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return queryResult;\r
+ }\r
+\r
+ private String operationsInstanceQuery(UserId userId, QueryCondition queryCondition)\r
+ {\r
+ String queryResult = null;\r
+ fetchOperationsInstance(userId);\r
+ List<Operation> operationList = operations.getOperation();\r
+\r
+ //todo\r
+\r
+ return queryResult;\r
+ }\r
+\r
+\r
+ private void fetchObjectsInstance(UserId userId)\r
+ {\r
+ UserKey userKey = new UserKey(userId);\r
+ InstanceIdentifier<Objects> objectsId = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).build();\r
+ ListenableFuture<Optional<Objects>> objectsFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, objectsId);\r
+ Futures.addCallback(objectsFuture, new FutureCallback<Optional<Objects>>() {\r
+ @Override\r
+ public void onSuccess(Optional<Objects> result)\r
+ {\r
+ setObjects(result.get());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t)\r
+ {\r
+ LOG.error("Can not read objects instances.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ }\r
+\r
+ private void fetchOperationsInstance(UserId userId)\r
+ {\r
+ UserKey userKey = new UserKey(userId);\r
+ InstanceIdentifier<Operations> operationsId = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Operations.class).build();\r
+ ListenableFuture<Optional<Operations>> operationsFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, operationsId);\r
+ Futures.addCallback(operationsFuture, new FutureCallback<Optional<Operations>>() {\r
+ @Override\r
+ public void onSuccess(Optional<Operations> result)\r
+ {\r
+ setOperations(result.get());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t)\r
+ {\r
+ LOG.error("Can not read operations instances.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ }\r
+\r
+ private void setObjects(Objects objects)\r
+ {\r
+ this.objects = objects;\r
+ }\r
+ private void setOperations(Operations operations)\r
+ {\r
+ this.operations = operations;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.advancedquery;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.QueryConditionDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.advanced.nemo.query.input.QueryCondition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.query.condition.definitions.QueryConditionDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.query.condition.definitions.query.condition.definition.QueryConditionMatchPatterns;\r
+import com.google.common.base.Optional;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/16.\r
+ */\r
+public class QueryDefinitionCheck {\r
+ private DataBroker dataBroker;\r
+ private List<QueryConditionDefinition> queryConditionDefinitions;\r
+ private static final Logger LOG = LoggerFactory.getLogger(QueryDefinitionCheck.class);\r
+\r
+ public QueryDefinitionCheck(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ queryConditionDefinitions = null;\r
+ }\r
+\r
+ public String CheckQueryDefinition(QueryCondition queryCondition)\r
+ {\r
+ fetchQueryConditionDefinitionList();\r
+ Boolean conditionexist = false;\r
+ String errorInfo = null;\r
+ if (queryConditionDefinitions != null)\r
+ {\r
+ for (QueryConditionDefinition queryConditionDefinition : queryConditionDefinitions)\r
+ {\r
+ if (queryConditionDefinition.getQueryConditionName().equals(queryCondition.getQueryConditionName()))\r
+ {\r
+ conditionexist = true;\r
+\r
+ if (queryCondition.getQueryIntentType() != null)\r
+ {\r
+ if (queryConditionDefinition.getQueryIntentType() != null)\r
+ {\r
+ if (queryCondition.getQueryIntentType().getIntValue() != queryConditionDefinition.getQueryIntentType().getIntValue())\r
+ {\r
+ errorInfo = "The query target is not consistent with the definition.";\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no query intent type defined in this query condition.";\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (queryCondition.getQueryConditionTargetValue() != null)\r
+ {\r
+ if (queryConditionDefinition.getQueryConditionValueType() != null)\r
+ {\r
+ QueryConditionDefinition.QueryConditionValueType queryConditionValueType = queryConditionDefinition.getQueryConditionValueType();\r
+ if (queryConditionValueType.getIntValue() == 0 && !(queryCondition.getQueryConditionTargetValue().getIntValue() == null && queryCondition.getQueryConditionTargetValue().getStringValue() != null && queryCondition.getQueryConditionTargetValue().getRangeValue() == null))\r
+ {\r
+ errorInfo = "The property value type should be string";\r
+ break;\r
+ }\r
+ else if (queryConditionValueType.getIntValue() == 1 && !(queryCondition.getQueryConditionTargetValue().getIntValue() != null && queryCondition.getQueryConditionTargetValue().getStringValue() == null && queryCondition.getQueryConditionTargetValue().getRangeValue() == null))\r
+ {\r
+ errorInfo = "The property value type should be integer";\r
+ break;\r
+ }\r
+ else if (queryConditionValueType.getIntValue() == 2 && !(queryCondition.getQueryConditionTargetValue().getIntValue() == null && queryCondition.getQueryConditionTargetValue().getStringValue() == null && queryCondition.getQueryConditionTargetValue().getRangeValue() != null))\r
+ {\r
+ errorInfo = "The property value type should be range";\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no query condition value type defined in query condition.";\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (queryCondition.getQueryConditionMatchPattern() != null)\r
+ {\r
+ if (queryConditionDefinition.getQueryConditionMatchPatterns() != null)\r
+ {\r
+ if (queryConditionDefinition.getQueryConditionMatchPatterns().getQueryConditionMatchPattern() != null)\r
+ {\r
+ List<QueryConditionMatchPatterns.QueryConditionMatchPattern> queryConditionMatchPatternList= queryConditionDefinition.getQueryConditionMatchPatterns().getQueryConditionMatchPattern();\r
+ if (!queryConditionMatchPatternList.contains(queryCondition.getQueryConditionMatchPattern()))\r
+ {\r
+ errorInfo = "The query condition match type pattern is not included in the definitions.";\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no query condition list defined in query condition.";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no query condition match patterns defined in query condition.";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!conditionexist)\r
+ {\r
+ errorInfo = "The condition has not been defined.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void fetchQueryConditionDefinitionList()\r
+ {\r
+ InstanceIdentifier<QueryConditionDefinitions> queryCondiDefInsIdentifier = InstanceIdentifier.builder(QueryConditionDefinitions.class).build();\r
+ ListenableFuture<Optional<QueryConditionDefinitions>> querydefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, queryCondiDefInsIdentifier);\r
+ Futures.addCallback(querydefinitionFuture, new FutureCallback<Optional<QueryConditionDefinitions>>() {\r
+ @Override\r
+ public void onSuccess(Optional<QueryConditionDefinitions> result)\r
+ {\r
+ setQueryConditionDefinitions(result.get().getQueryConditionDefinition());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t)\r
+ {\r
+ LOG.error("Can not read query definition information.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ return ;\r
+ }\r
+\r
+ private void setQueryConditionDefinitions(List<QueryConditionDefinition> queryConditionDefinitions)\r
+ {\r
+ this.queryConditionDefinitions = queryConditionDefinitions;\r
+ }\r
+ }\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.tenantmanager;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserPassword;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserRoleName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/29.\r
+ */\r
+\r
+/* test user-name and user-password */\r
+public class AAA {\r
+\r
+ private TenantManage tenantManage;\r
+\r
+ public AAA(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String CheckUser(UserId userId, UserName userName, UserPassword userPassword, UserRoleName userRoleName)\r
+ {\r
+ tenantManage.fetchUsers();\r
+ List<User> userList = tenantManage.getUsersList();\r
+ String errorInfo = null;\r
+ Boolean userexist = false;\r
+\r
+ if (userList != null)\r
+ {\r
+ for (User user : userList)\r
+ {\r
+ if (user.getUserId().equals(userId))\r
+ {\r
+ userexist = true;\r
+ if (!user.getUserName().equals(userName))\r
+ {\r
+ errorInfo = "The user name is not right.";\r
+ break;\r
+ }\r
+ else if (!user.getUserPassword().equals(userPassword))\r
+ {\r
+ errorInfo = "The password is not right.";\r
+ break;\r
+ }\r
+ else if (!user.getUserRole().equals(userRoleName))\r
+ {\r
+ errorInfo = "The role is not right.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ if (!userexist)\r
+ {\r
+ errorInfo = "The user is not exist.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.tenantmanager;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserRoleName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.RegisterUserInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.user.rev151010.user.roles.UserRole;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/20.\r
+ */\r
+public class RegisterUser {\r
+ private TenantManage tenantManage;\r
+ private List<UserRole> userRoleList;\r
+ private List<User> usersList;\r
+\r
+ public RegisterUser(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String registerUser(RegisterUserInput input)\r
+ {\r
+ String errorInfo = null;\r
+\r
+ tenantManage.fetchUserRoles();\r
+ userRoleList = tenantManage.getUserRoleList();\r
+ tenantManage.fetchUsers();\r
+ usersList = tenantManage.getUsersList();\r
+\r
+ if (userRoleList == null)\r
+ {\r
+ errorInfo = "There are no roles be defined.";\r
+ }\r
+ else\r
+ {\r
+ if (IfRoleExist(input.getUserRole()))\r
+ {\r
+ if (usersList != null && IfUserHasRegistered(input.getUserId()))\r
+ {\r
+ errorInfo = "The user has been registered.";\r
+ }\r
+ else\r
+ {\r
+ tenantManage.addUser(input);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "The role is not defined in the data store.";\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+ private boolean IfRoleExist(UserRoleName userRoleName){\r
+ Boolean roleExist = false;\r
+\r
+ for (UserRole userRole : userRoleList)\r
+ {\r
+ if (userRole.getRoleName().equals(userRoleName))\r
+ {\r
+ roleExist = true;\r
+ }\r
+ }\r
+\r
+ return roleExist;\r
+ }\r
+\r
+ private boolean IfUserHasRegistered(UserId userId){\r
+ Boolean userHasRegistered = false;\r
+\r
+ for (User user : usersList)\r
+ {\r
+ if (user.getUserId().equals(userId))\r
+ {\r
+ userHasRegistered = true;\r
+ }\r
+ }\r
+\r
+ return userHasRegistered;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.tenantmanager;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.RegisterUserInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.user.rev151010.UserRoles;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.user.rev151010.user.roles.UserRole;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/29.\r
+ */\r
+\r
+/* maintain tenant information, including how many tenants are active, their information */\r
+public class TenantManage {\r
+ private static final Logger LOG = LoggerFactory.getLogger(TenantManage.class);\r
+ private DataBroker dataBroker;\r
+ private List<UserRole> userRoleList;\r
+ private List<User> usersList ;\r
+ private User user;\r
+\r
+ public TenantManage(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ }\r
+\r
+ private void setUserRoleList(List<UserRole> userRoleList)\r
+ {\r
+ this.userRoleList = userRoleList;\r
+ }\r
+\r
+ private void setUserList(List<User> userList)\r
+ {\r
+ this.usersList = userList;\r
+ }\r
+\r
+ private void setUser(User user)\r
+ {\r
+ this.user = user;\r
+ }\r
+\r
+ public List<UserRole> getUserRoleList()\r
+ {\r
+ return userRoleList;\r
+ }\r
+\r
+ public List<User> getUsersList()\r
+ {\r
+ return usersList;\r
+ }\r
+\r
+ public User getUser()\r
+ {\r
+ return user;\r
+ }\r
+\r
+ public void fetchUserRoles(){\r
+\r
+ InstanceIdentifier<UserRoles> userRolesInsId = InstanceIdentifier.builder(UserRoles.class).build();\r
+ ListenableFuture<Optional<UserRoles>> userRolesFuture = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, userRolesInsId);\r
+ Futures.addCallback(userRolesFuture, new FutureCallback<Optional<UserRoles>>() {\r
+ @Override\r
+ public void onSuccess(Optional<UserRoles> result)\r
+ {\r
+ setUserRoleList(result.get().getUserRole());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t)\r
+ {\r
+ LOG.error("Can not read role information.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ return;\r
+ }\r
+\r
+ public void fetchUsers(){\r
+ InstanceIdentifier<Users> usersInsId = InstanceIdentifier.builder(Users.class).build();\r
+ ListenableFuture<Optional<Users>> usersFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, usersInsId);\r
+ Futures.addCallback(usersFuture, new FutureCallback<Optional<Users>>() {\r
+ @Override\r
+ public void onSuccess(Optional<Users> result)\r
+ {\r
+ setUserList(result.get().getUser());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t)\r
+ {\r
+ LOG.error("Can not read users information.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ return;\r
+ }\r
+\r
+ public void fetchVNSpace(UserId userId)\r
+ {\r
+ fetchUsers();\r
+ if (getUsersList() != null)\r
+ {\r
+ for (User user : getUsersList())\r
+ {\r
+ if (user.getUserId().equals(userId))\r
+ {\r
+ setUser(user);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ public void addUser(RegisterUserInput registerUserInput){\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ if (registerUserInput.getUserId() != null)\r
+ {\r
+ User user = new UserBuilder(registerUserInput).build();\r
+// UserBuilder userBuilder = new UserBuilder();\r
+// userBuilder.setUserId(registerUserInput.getUserId());\r
+// userBuilder.setUserName(registerUserInput.getUserName());\r
+// userBuilder.setUserPassword(registerUserInput.getUserPassword());\r
+// userBuilder.setUserRole(registerUserInput.getUserRole());\r
+//\r
+// User user = userBuilder.build();\r
+ UserKey userKey = new UserKey(registerUserInput.getUserId());\r
+\r
+ InstanceIdentifier<User> userid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).build();\r
+\r
+ t.put(LogicalDatastoreType.CONFIGURATION, userid, user,true);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+\r
+ }\r
+ });\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.transactionmanager;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.BeginTransactionInput;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class TransactionBegin {\r
+\r
+ public String transactionbegin(AAA aaa,BeginTransactionInput input)\r
+ {\r
+ String errorInfo = null;\r
+ errorInfo = aaa.CheckUser(input.getUserId(),input.getUserName(),input.getUserPassword(),input.getUserRole());\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.transactionmanager;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.EndTransactionInput;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class TransactionEnd {\r
+ public String transactionend(AAA aaa,EndTransactionInput input)\r
+ {\r
+ String errorInfo = null;\r
+ errorInfo = aaa.CheckUser(input.getUserId(),input.getUserName(),input.getUserPassword(),input.getUserRole());\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.NodeInstance;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/6.\r
+ */\r
+public class VNSpaceManagement {\r
+ private DataBroker dataBroker;\r
+\r
+ public VNSpaceManagement(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ }\r
+\r
+ public NodeInstance getNodeInstance(UserId userId, NodeId nodeId) {\r
+ // TODO\r
+\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.instancecheck;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.EndNode;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/10.\r
+ */\r
+public class ConnectionInstanceCheck {\r
+ private TenantManage tenantManage;\r
+\r
+ public ConnectionInstanceCheck(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String checkConnInstance(UserId userId, Connection connection)\r
+ {\r
+ String errorInfo = null;\r
+ tenantManage.fetchVNSpace(userId);\r
+ User user = tenantManage.getUser();\r
+\r
+ if (user != null)\r
+ {\r
+ if (user.getObjects() != null)\r
+ {\r
+ if (user.getObjects().getConnection() != null)\r
+ {\r
+ List<Connection> connectionList = tenantManage.getUser().getObjects().getConnection();\r
+\r
+ for (Connection connection1 : connectionList)\r
+ {\r
+ if (connection1.getConnectionId().equals(connection.getConnectionId()))\r
+ {\r
+ if (!connection1.getConnectionType().equals(connection.getConnectionType()))\r
+ {\r
+ errorInfo = "The connection type should not be changed.";\r
+ break;\r
+ }\r
+ if (!connection1.getConnectionName().equals(connection.getConnectionName()))\r
+ {\r
+ errorInfo = "The End node should not be changed.";\r
+ break;\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+ if (user.getObjects().getNode() != null)\r
+ {\r
+ List<EndNode> nodeList = connection.getEndNode();\r
+ List<Node> nodeList1 = user.getObjects().getNode();\r
+\r
+ for (EndNode endNode : nodeList)\r
+ {\r
+ Boolean EndNodeExist = false;\r
+ for (Node node : nodeList1)\r
+ {\r
+ if (node.getNodeId().equals(endNode.getNodeId()))\r
+ {\r
+ EndNodeExist = true;\r
+ break;\r
+ }\r
+ }\r
+ if ( !EndNodeExist)\r
+ {\r
+ errorInfo = "There are no endnode" + endNode.getNodeId().toString() +" in this user vn space.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (connection.getEndNode() != null)\r
+ {\r
+ errorInfo = "There are no nodes in user vn space.";\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (connection.getEndNode() != null)\r
+ {\r
+ errorInfo = "There are no nodes in user vn space.";\r
+ }\r
+ }\r
+\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.instancecheck;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/10.\r
+ */\r
+public class FlowInstanceCheck {\r
+ private TenantManage tenantManage;\r
+\r
+ public FlowInstanceCheck(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String checkFlowInstance(UserId userId, Flow flow)\r
+ {\r
+ String errorInfo = null;\r
+\r
+ tenantManage.fetchVNSpace(userId);\r
+\r
+\r
+ User user = tenantManage.getUser();\r
+ if (user != null)\r
+ {\r
+ if (user.getObjects() != null)\r
+ {\r
+ if (user.getObjects().getFlow() != null)\r
+ {\r
+ List<Flow> flowList = tenantManage.getUser().getObjects().getFlow();\r
+ for (Flow flow1 : flowList)\r
+ {\r
+ if (flow1.getFlowId() == flow.getFlowId())\r
+ {\r
+ if (flow1.getFlowName() != flow.getFlowName())\r
+ {\r
+ errorInfo = "The flow name should not be changed.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.instancecheck;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/10.\r
+ */\r
+public class NodeInstanceCheck {\r
+\r
+ private TenantManage tenantManage;\r
+\r
+ public NodeInstanceCheck(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String checkNodeInstance(UserId userId, Node node)\r
+ {\r
+ String errorInfo = null;\r
+ tenantManage.fetchVNSpace(userId);\r
+ User user = tenantManage.getUser();\r
+ if (user != null)\r
+ {\r
+ Objects objects = user.getObjects();\r
+ if (objects != null)\r
+ {\r
+ if (objects.getNode() != null)\r
+ {\r
+ List<Node> nodeList = objects.getNode();\r
+\r
+ for (Node node1 : nodeList)\r
+ {\r
+ if (node1.getNodeId().equals(node.getNodeId()))\r
+ {\r
+ if ( !node1.getNodeName().equals(node.getNodeName()))\r
+ {\r
+ errorInfo = "The node name should not be changed.";\r
+ break;\r
+ }\r
+ if (!node1.getNodeType().equals(node.getNodeType()))\r
+ {\r
+ errorInfo = "The node type should not be changed.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.instancecheck;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/10.\r
+ */\r
+public class OperationInstanceCheck {\r
+ private TenantManage tenantManage;\r
+\r
+ public OperationInstanceCheck(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String checkOperationInstance(UserId userId, Operation operation)\r
+ {\r
+ String errorInfo = null;\r
+\r
+ tenantManage.fetchVNSpace(userId);\r
+\r
+ User user = tenantManage.getUser();\r
+ if (user != null)\r
+ {\r
+ if (operation.getTargetObject() != null && user.getObjects() == null)\r
+ {\r
+ errorInfo = "There are no objects in data store.";\r
+ }\r
+ if (operation.getTargetObject() != null && user.getObjects() != null)\r
+ {\r
+ Objects objects = user.getObjects();\r
+ Boolean targetExist = false;\r
+\r
+ if (objects.getNode() != null )\r
+ {\r
+ List<Node> nodeList = objects.getNode();\r
+ for (Node node:nodeList)\r
+ {\r
+ if (node.getNodeId().getValue().equals(operation.getTargetObject().getValue()))\r
+ {\r
+ targetExist = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (objects.getConnection() != null)\r
+ {\r
+ List<Connection> connectionList = objects.getConnection();\r
+ for (Connection connection : connectionList)\r
+ {\r
+ if (connection.getConnectionId().getValue().equals(operation.getTargetObject().getValue()))\r
+ {\r
+ targetExist = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (objects.getFlow() != null)\r
+ {\r
+ List<Flow> flowList = objects.getFlow();\r
+ for (Flow flow : flowList)\r
+ {\r
+ if (flow.getFlowId().getValue().equals(operation.getTargetObject().getValue()))\r
+ {\r
+ targetExist = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (!targetExist)\r
+ {\r
+ errorInfo ="The target object is not included in vn space.";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (user.getOperations() != null)\r
+ {\r
+ if (user.getOperations().getOperation() != null)\r
+ {\r
+ List<Operation> operationList = tenantManage.getUser().getOperations().getOperation();\r
+ for (Operation operation1 : operationList)\r
+ {\r
+ if (operation1.getOperationId().equals(operation.getOperationId()))\r
+ {\r
+ if (!operation1.getOperationName().equals(operation.getOperationName()))\r
+ {\r
+ errorInfo = "The operation name should not be changed.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (operation.getTargetObject() != null)\r
+ {\r
+ errorInfo = "There are no objects in data store.";\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.instancecheck;\r
+\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Results;\r
+\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/10.\r
+ */\r
+public class ResultInstanceCheck {\r
+ private TenantManage tenantManage;\r
+\r
+ public ResultInstanceCheck(TenantManage tenantManage)\r
+ {\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String checkResultInstance(UserId userId,Results results)\r
+ {\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.languagestyle;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.LanguageStyleNemoRequestInput;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class LanguageIntent {\r
+\r
+ private DataBroker dataBroker;\r
+\r
+ public LanguageIntent(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ }\r
+\r
+ public String LanIntentHandler(AAA aaa, LanguageStyleNemoRequestInput languageStyleNemoRequestInput){\r
+\r
+ String errorInfo = null;\r
+\r
+ errorInfo = aaa.CheckUser(languageStyleNemoRequestInput.getUserId(),languageStyleNemoRequestInput.getUserName(),languageStyleNemoRequestInput.getUserPassword(),languageStyleNemoRequestInput.getUserRole());\r
+ if (errorInfo !=null)\r
+ {\r
+ return errorInfo;\r
+ }\r
+ else\r
+ {\r
+ //TODO language parse\r
+ }\r
+\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ConnectionId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.ConnectionKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class DeleteConnection {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private static final Logger LOG = LoggerFactory.getLogger(DeleteConnection.class);\r
+\r
+ public DeleteConnection(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String DeleteConnectionHandling(UserId userId, ConnectionId connectionId)\r
+ {\r
+ Boolean ConnInstanceExist = false;\r
+ String errorInfo = null;\r
+\r
+ tenantManage.fetchVNSpace(userId);\r
+ User user = tenantManage.getUser();\r
+\r
+ if (user != null)\r
+ {\r
+ if (user.getObjects() != null)\r
+ {\r
+ if (user.getObjects().getConnection() != null)\r
+ {\r
+ List<Connection> connectionList = tenantManage.getUser().getObjects().getConnection();\r
+\r
+ for (Connection connection : connectionList)\r
+ {\r
+ if (connection.getConnectionId().equals(connectionId))\r
+ {\r
+ ConnInstanceExist = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (ConnInstanceExist)\r
+ {\r
+ DeleteConnInstance(userId, connectionId);\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "The connection instance"+connectionId.toString()+ "is not exit. Could not be deleted.";\r
+ }\r
+\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no connection instances in data store.";\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no connection instances in data store.";\r
+ }\r
+\r
+ return errorInfo;\r
+ }\r
+\r
+ private void DeleteConnInstance(UserId userId, ConnectionId connectionId)\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ UserKey userKey = new UserKey(userId);\r
+ ConnectionKey connectionKey = new ConnectionKey(connectionId);\r
+\r
+ InstanceIdentifier<Connection> connectionid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).child(Connection.class,connectionKey).build();\r
+ t.delete(LogicalDatastoreType.CONFIGURATION, connectionid);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.FlowId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.FlowKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class DeleteFlow {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private static final Logger LOG = LoggerFactory.getLogger(DeleteFlow.class);\r
+\r
+ public DeleteFlow(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String DeleteFlowHandling(UserId userId, FlowId flowId)\r
+ {\r
+ Boolean FlowInsExist = false;\r
+ tenantManage.fetchVNSpace(userId);\r
+ String errorInfo = null;\r
+ User user = tenantManage.getUser();\r
+\r
+ if (user != null)\r
+ {\r
+ if (user.getObjects() != null)\r
+ {\r
+ if (user.getObjects().getFlow() != null)\r
+ {\r
+ List<Flow> flowList = tenantManage.getUser().getObjects().getFlow();\r
+ for (Flow flow : flowList)\r
+ {\r
+ if (flow.getFlowId().equals(flowId))\r
+ {\r
+ FlowInsExist = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FlowInsExist)\r
+ {\r
+ DeleteFlowInstance(userId,flowId);\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "The flow instance" +flowId.toString()+"is not exist. Could not be deleted.";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no flow instances in the data store.";\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no user in the data store.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void DeleteFlowInstance(UserId userId, FlowId flowId)\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ UserKey userKey = new UserKey(userId);\r
+ FlowKey flowKey = new FlowKey(flowId);\r
+\r
+ InstanceIdentifier<Flow> flowid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).child(Flow.class,flowKey).build();\r
+ t.delete(LogicalDatastoreType.CONFIGURATION, flowid);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ConnectionId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.FlowId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.OperationId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.StructureStyleNemoDeleteInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.structure.style.nemo.delete.input.Results;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class DeleteIntent {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private DeleteNode deleteNode;\r
+ private DeleteConnection deleteConnection;\r
+ private DeleteFlow deleteFlow;\r
+ private DeleteOperation deleteOperation;\r
+ private DeleteResult deleteResult;\r
+\r
+ public DeleteIntent(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ deleteNode = new DeleteNode(dataBroker, tenantManage);\r
+ deleteConnection = new DeleteConnection(dataBroker,tenantManage);\r
+ deleteFlow = new DeleteFlow(dataBroker,tenantManage);\r
+ deleteOperation = new DeleteOperation(dataBroker,tenantManage);\r
+ deleteResult = new DeleteResult();\r
+ }\r
+\r
+ public String styleNemoDeleteOutput(AAA aaa,StructureStyleNemoDeleteInput styleNemoDeleteInput)\r
+ {\r
+ String errorInfo = null;\r
+\r
+ errorInfo = aaa.CheckUser(styleNemoDeleteInput.getUserId(),styleNemoDeleteInput.getUserName(),styleNemoDeleteInput.getUserPassword(),styleNemoDeleteInput.getUserRole());\r
+\r
+ if (errorInfo != null)\r
+ {\r
+ return errorInfo;\r
+ }\r
+\r
+ else\r
+ {\r
+ if (styleNemoDeleteInput.getObjects() != null)\r
+ {\r
+ if (styleNemoDeleteInput.getObjects().getNode() != null && errorInfo == null)\r
+ {\r
+ List<NodeId> nodeIdList= styleNemoDeleteInput.getObjects().getNode();\r
+ for (NodeId nodeId : nodeIdList)\r
+ {\r
+ errorInfo = deleteNode.DeleNodeHandling(styleNemoDeleteInput.getUserId(), nodeId);\r
+ if (errorInfo != null) {\r
+ break;\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ if (styleNemoDeleteInput.getObjects().getConnection() != null && errorInfo == null)\r
+ {\r
+ List<ConnectionId> connectionIdList = styleNemoDeleteInput.getObjects().getConnection();\r
+ for (ConnectionId connectionId : connectionIdList)\r
+ {\r
+ errorInfo = deleteConnection.DeleteConnectionHandling(styleNemoDeleteInput.getUserId(),connectionId);\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ if (styleNemoDeleteInput.getObjects().getFlow() != null && errorInfo == null)\r
+ {\r
+ List<FlowId> flowIdList = styleNemoDeleteInput.getObjects().getFlow();\r
+ for (FlowId flowId : flowIdList )\r
+ {\r
+ errorInfo = deleteFlow.DeleteFlowHandling(styleNemoDeleteInput.getUserId(),flowId);\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+ }\r
+ if (styleNemoDeleteInput.getOperations() != null)\r
+ {\r
+ if (styleNemoDeleteInput.getOperations().getOperation() != null && errorInfo == null)\r
+ {\r
+ List<OperationId> operationIdList = styleNemoDeleteInput.getOperations().getOperation();\r
+ for (OperationId operationId : operationIdList)\r
+ {\r
+ errorInfo = deleteOperation.DeleteOperationhandling(styleNemoDeleteInput.getUserId(),operationId);\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+ }\r
+\r
+ if (styleNemoDeleteInput.getResults() != null)\r
+ {\r
+ Results results = styleNemoDeleteInput.getResults();\r
+ errorInfo = deleteResult.DeleteResultHandling(styleNemoDeleteInput.getUserId(),results);\r
+ if (errorInfo != null)\r
+ {\r
+ return errorInfo;\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.NodeKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class DeleteNode {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private static final Logger LOG = LoggerFactory.getLogger(DeleteNode.class);\r
+\r
+ public DeleteNode(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String DeleNodeHandling(UserId userId,NodeId nodeId)\r
+ {\r
+ String errorInfo = null;\r
+ Boolean NodeInstanceExist = false;\r
+\r
+ tenantManage.fetchVNSpace(userId);\r
+\r
+ User user = tenantManage.getUser();\r
+ if (user != null)\r
+ {\r
+ if (user.getObjects() != null)\r
+ {\r
+ if (user.getObjects().getNode() != null)\r
+ {\r
+ List<Node> nodeList = tenantManage.getUser().getObjects().getNode();\r
+\r
+ for (Node node : nodeList)\r
+ {\r
+ if (node.getNodeId().equals(nodeId))\r
+ {\r
+ NodeInstanceExist = true;\r
+ break;\r
+ }\r
+ }\r
+ if (NodeInstanceExist)\r
+ {\r
+ DeleteNodeInstance(userId,nodeId);\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "The node instance" +nodeId.toString()+"is not exist.Could not be deleted";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no nodes instances in data store.";\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no user in data store.";\r
+ }\r
+\r
+ return errorInfo;\r
+ }\r
+\r
+ private void DeleteNodeInstance(UserId userId,NodeId nodeId)\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ UserKey userKey = new UserKey(userId);\r
+ NodeKey nodeKey = new NodeKey(nodeId);\r
+\r
+ InstanceIdentifier<Node> nodeid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).child(Node.class,nodeKey).build();\r
+ t.delete(LogicalDatastoreType.CONFIGURATION, nodeid);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.OperationId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Operations;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.OperationKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class DeleteOperation {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private static final Logger LOG = LoggerFactory.getLogger(DeleteOperation.class);\r
+\r
+ public DeleteOperation(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ }\r
+\r
+ public String DeleteOperationhandling(UserId userId, OperationId operationId)\r
+ {\r
+ Boolean OperationExist = false;\r
+ String errorInfo = null;\r
+ tenantManage.fetchVNSpace(userId);\r
+\r
+ User user = tenantManage.getUser();\r
+\r
+ if (user != null)\r
+ {\r
+ if (user.getOperations() != null)\r
+ {\r
+ if (user.getOperations().getOperation() != null)\r
+ {\r
+ List<Operation> operationList = tenantManage.getUser().getOperations().getOperation();\r
+\r
+ for (Operation operation : operationList)\r
+ {\r
+ if (operation.getOperationId().equals(operationId))\r
+ {\r
+ OperationExist = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (OperationExist)\r
+ {\r
+ DeleteOperationInstance(userId,operationId);\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "The operation instance" +operationId.toString()+"is not exist. Could not be deleted.";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no operation instances in the data store.";\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no user in the data store.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void DeleteOperationInstance(UserId userId, OperationId operationId)\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ UserKey userKey = new UserKey(userId);\r
+ OperationKey operationKey = new OperationKey(operationId);\r
+\r
+ InstanceIdentifier<Operation> operationid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Operations.class).child(Operation.class,operationKey).build();\r
+ t.delete(LogicalDatastoreType.CONFIGURATION, operationid);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.deleteintent;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.structure.style.nemo.delete.input.Results;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class DeleteResult {\r
+\r
+ public String DeleteResultHandling(UserId userId, Results results)\r
+ {\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.nemo.user.vnspacemanager.instancecheck.ConnectionInstanceCheck;\r
+import org.opendaylight.nemo.user.vnspacemanager.syntaxcheck.ConnectionDefinitionCheck;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.ConnectionBuilder;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.ConnectionKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class UpdateConnection {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private ConnectionDefinitionCheck connectionDefinitionCheck;\r
+ private ConnectionInstanceCheck connectionInstanceCheck;\r
+ private static final Logger LOG = LoggerFactory.getLogger(UpdateConnection.class);\r
+\r
+ public UpdateConnection(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ connectionDefinitionCheck = new ConnectionDefinitionCheck(dataBroker);\r
+ connectionInstanceCheck = new ConnectionInstanceCheck(tenantManage);\r
+ }\r
+\r
+ public String ConnectionHandling(UserId userId, Connection connection)\r
+ {\r
+ String errorDefinition = connectionDefinitionCheck.CheckConnectionDefinition(connection);\r
+ String errorInstance = connectionInstanceCheck.checkConnInstance(userId,connection);\r
+ if (errorDefinition != null)\r
+ {\r
+ return errorDefinition;\r
+ }\r
+ if (errorInstance != null)\r
+ {\r
+ return errorInstance;\r
+ }\r
+ else\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ if (userId != null && connection != null)\r
+ {\r
+// ConnectionBuilder connectionBuilder = new ConnectionBuilder();\r
+// connectionBuilder.setConnectionId(connection.getConnectionId());\r
+// connectionBuilder.setConnectionName(connection.getConnectionName());\r
+// connectionBuilder.setConnectionType(connection.getConnectionType());\r
+// connectionBuilder.setEndNode(connection.getEndNode());\r
+// connectionBuilder.setProperty(connection.getProperty());\r
+//\r
+// Connection connection1 = connectionBuilder.build();\r
+\r
+ Connection connection1 = new ConnectionBuilder(connection).build();\r
+ ConnectionKey connectionKey = new ConnectionKey(connection.getConnectionId());\r
+\r
+ UserKey userKey = new UserKey(userId);\r
+\r
+ InstanceIdentifier<Connection> connectionid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).child(Connection.class,connectionKey).build();\r
+ t.put(LogicalDatastoreType.CONFIGURATION, connectionid, connection1,true);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.nemo.user.vnspacemanager.instancecheck.FlowInstanceCheck;\r
+import org.opendaylight.nemo.user.vnspacemanager.syntaxcheck.FlowDefinitionCheck;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.FlowBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.FlowKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class UpdateFlow {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private FlowDefinitionCheck flowDefinitionCheck;\r
+ private FlowInstanceCheck flowInstanceCheck;\r
+ private static final Logger LOG = LoggerFactory.getLogger(UpdateFlow.class);\r
+\r
+ public UpdateFlow(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ flowDefinitionCheck = new FlowDefinitionCheck(dataBroker);\r
+ flowInstanceCheck = new FlowInstanceCheck(tenantManage);\r
+ }\r
+\r
+ public String FlowHandling(UserId userId, Flow flow)\r
+ {\r
+ String errorDefinition = flowDefinitionCheck.CheckDefinition(flow);\r
+ String errorInstance = flowInstanceCheck.checkFlowInstance(userId,flow);\r
+\r
+ if (errorDefinition != null)\r
+ {\r
+ return errorDefinition;\r
+ }\r
+ if (errorInstance != null)\r
+ {\r
+ return errorInstance;\r
+ }\r
+ else\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ if (userId!=null && flow!=null)\r
+ {\r
+// FlowBuilder flowBuilder = new FlowBuilder();\r
+// flowBuilder.setFlowId(flow.getFlowId());\r
+// flowBuilder.setFlowName(flow.getFlowName());\r
+// flowBuilder.setMatchItem(flow.getMatchItem());\r
+// flowBuilder.setProperty(flow.getProperty());\r
+//\r
+// Flow flow1 = flowBuilder.build();\r
+ Flow flow1 = new FlowBuilder(flow).build();\r
+ FlowKey flowKey = new FlowKey(flow.getFlowId());\r
+\r
+ UserKey userKey = new UserKey(userId);\r
+\r
+ InstanceIdentifier<Flow> flowid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).child(Flow.class,flowKey).build();\r
+ t.put(LogicalDatastoreType.CONFIGURATION, flowid, flow1,true);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.AAA;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.StructureStyleNemoUpdateInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Results;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class UpdateIntent {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private UpdateNode updateNode;\r
+ private UpdateConnection updateConnection;\r
+ private UpdateFlow updateFlow;\r
+ private UpdateOperation updateOperation;\r
+ private UpdateResult updateResult;\r
+\r
+ public UpdateIntent(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ updateNode = new UpdateNode(dataBroker,tenantManage);\r
+ updateConnection = new UpdateConnection(dataBroker,tenantManage);\r
+ updateFlow = new UpdateFlow(dataBroker,tenantManage);\r
+ updateOperation = new UpdateOperation(dataBroker,tenantManage);\r
+ updateResult = new UpdateResult(dataBroker,tenantManage);\r
+ }\r
+\r
+ public String updateIntent(AAA aaa,StructureStyleNemoUpdateInput structureStyleNemoUpdateInput){\r
+\r
+ String erroInfo = null;\r
+\r
+ erroInfo = aaa.CheckUser(structureStyleNemoUpdateInput.getUserId(),structureStyleNemoUpdateInput.getUserName(),structureStyleNemoUpdateInput.getUserPassword(),structureStyleNemoUpdateInput.getUserRole());\r
+\r
+ if (erroInfo != null)\r
+ {\r
+ return erroInfo;\r
+ }\r
+ else\r
+ {\r
+ if(structureStyleNemoUpdateInput.getObjects() != null)\r
+ {\r
+ if (structureStyleNemoUpdateInput.getObjects().getNode() != null && erroInfo == null)\r
+ {\r
+ List<Node> nodeList= structureStyleNemoUpdateInput.getObjects().getNode();\r
+ for (Node node : nodeList )\r
+ {\r
+ erroInfo = updateNode.NodeHandling(structureStyleNemoUpdateInput.getUserId(), node);\r
+ if (erroInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (structureStyleNemoUpdateInput.getObjects().getConnection() != null && erroInfo == null)\r
+ {\r
+ List<Connection> connectionList = structureStyleNemoUpdateInput.getObjects().getConnection();\r
+ for (Connection connection : connectionList)\r
+ {\r
+ erroInfo = updateConnection.ConnectionHandling(structureStyleNemoUpdateInput.getUserId(), connection);\r
+ if (erroInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (structureStyleNemoUpdateInput.getObjects().getFlow() != null && erroInfo == null)\r
+ {\r
+ List<Flow> flowList = structureStyleNemoUpdateInput.getObjects().getFlow();\r
+ for (Flow flow : flowList)\r
+ {\r
+ erroInfo = updateFlow.FlowHandling(structureStyleNemoUpdateInput.getUserId(),flow);\r
+ if (erroInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (structureStyleNemoUpdateInput.getOperations() != null)\r
+ {\r
+ if (structureStyleNemoUpdateInput.getOperations().getOperation() != null && erroInfo == null)\r
+ {\r
+ List<Operation> operationList =structureStyleNemoUpdateInput.getOperations().getOperation();\r
+ for (Operation operation : operationList)\r
+ {\r
+ erroInfo = updateOperation.OperationHandling(structureStyleNemoUpdateInput.getUserId(), operation);\r
+ if (erroInfo !=null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ else if (structureStyleNemoUpdateInput.getResults() != null)\r
+ {\r
+ if ( structureStyleNemoUpdateInput.getResults() != null && erroInfo == null)\r
+ {\r
+ Results results = structureStyleNemoUpdateInput.getResults();\r
+ erroInfo = updateResult.ResultHandling(structureStyleNemoUpdateInput.getUserId(), results);\r
+ if (erroInfo != null)\r
+ {\r
+ //todo\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return erroInfo;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.nemo.user.vnspacemanager.instancecheck.NodeInstanceCheck;\r
+import org.opendaylight.nemo.user.vnspacemanager.syntaxcheck.NodeDefinitionCheck;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.NodeBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.NodeKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class UpdateNode {\r
+\r
+ private DataBroker dataBroker;\r
+ private NodeDefinitionCheck nodeCheck;\r
+ private NodeInstanceCheck nodeInstanceCheck;\r
+ private static final Logger LOG = LoggerFactory.getLogger(UpdateNode.class);\r
+\r
+ public UpdateNode(DataBroker dataBroker,TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ nodeCheck = new NodeDefinitionCheck(dataBroker);\r
+ nodeInstanceCheck = new NodeInstanceCheck(tenantManage);\r
+ }\r
+\r
+ public String NodeHandling(UserId userId,Node node)\r
+ {\r
+ String errorDefinition = nodeCheck.CheckNodeDefinition(node);\r
+ String errorInstance = nodeInstanceCheck.checkNodeInstance(userId,node);\r
+\r
+ if (errorDefinition != null)\r
+ {\r
+ return errorDefinition;\r
+ }\r
+ if (errorInstance != null)\r
+ {\r
+ return errorInstance;\r
+ }\r
+ else\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ if (userId != null && node.getNodeId() !=null)\r
+ {\r
+// NodeBuilder nodeBuilder = new NodeBuilder();\r
+// nodeBuilder.setNodeId(node.getNodeId());\r
+// nodeBuilder.setNodeId(node.getNodeId());\r
+// nodeBuilder.setNodeName(node.getNodeName());\r
+// nodeBuilder.setSubNode(node.getSubNode());\r
+// nodeBuilder.setProperty(node.getProperty());\r
+// Node node1 = nodeBuilder.build();\r
+\r
+ Node node1 = new NodeBuilder(node).build();\r
+ NodeKey nodeKey = new NodeKey(node.getKey());\r
+\r
+ UserKey userKey = new UserKey(userId);\r
+\r
+ InstanceIdentifier<Node> nodeid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Objects.class).child(Node.class,nodeKey).build();\r
+ t.put(LogicalDatastoreType.CONFIGURATION, nodeid, node1,true);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ }\r
+ });\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.nemo.user.vnspacemanager.instancecheck.OperationInstanceCheck;\r
+import org.opendaylight.nemo.user.vnspacemanager.syntaxcheck.OperationDefinitionCheck;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Operations;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.OperationBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.OperationKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class UpdateOperation {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private OperationDefinitionCheck operationDefinitionCheck;\r
+ private OperationInstanceCheck operationInstanceCheck;\r
+ private static final Logger LOG = LoggerFactory.getLogger(UpdateOperation.class);\r
+\r
+ public UpdateOperation(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ operationDefinitionCheck = new OperationDefinitionCheck(dataBroker);\r
+ operationInstanceCheck = new OperationInstanceCheck(tenantManage);\r
+ }\r
+\r
+ public String OperationHandling(UserId userId, Operation operation)\r
+ {\r
+ String errorDefinition = operationDefinitionCheck.CheckDefinition(operation);\r
+ String errorInstance = operationInstanceCheck.checkOperationInstance(userId, operation);\r
+\r
+ if (errorDefinition != null)\r
+ {\r
+ return errorDefinition;\r
+ }\r
+ if (errorInstance != null)\r
+ {\r
+ return errorInstance;\r
+ }\r
+ else\r
+ {\r
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();\r
+ if (userId != null && operation.getOperationId() != null)\r
+ {\r
+// OperationBuilder operationBuilder = new OperationBuilder();\r
+// operationBuilder.setOperationId(operation.getOperationId());\r
+// operationBuilder.setOperationName(operation.getOperationName());\r
+// operationBuilder.setConditionSegment(operation.getConditionSegment());\r
+// operationBuilder.setTargetObject(operationBuilder.getTargetObject());\r
+// operationBuilder.setAction(operation.getAction());\r
+// operationBuilder.setPriority(operation.getPriority());\r
+//\r
+// Operation operation1 = operationBuilder.build();\r
+ Operation operation1 = new OperationBuilder(operation).build();\r
+ OperationKey operationKey = new OperationKey(operation.getOperationId());\r
+\r
+ UserKey userKey = new UserKey(userId);\r
+\r
+ InstanceIdentifier<Operation> operationid = InstanceIdentifier.builder(Users.class).child(User.class, userKey).child(Operations.class).child(Operation.class,operationKey).build();\r
+ t.put(LogicalDatastoreType.CONFIGURATION, operationid, operation1,true);\r
+ CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r
+ Futures.addCallback(f, new FutureCallback<Void>() {\r
+ @Override\r
+ public void onFailure(Throwable t) { \r
+ LOG.error("Could not write endpoint base container", t);\r
+ }\r
+\r
+ @Override\r
+ public void onSuccess(Void result) {\r
+ \r
+ }\r
+ });\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.structurestyle.updateintent;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.nemo.user.tenantmanager.TenantManage;\r
+import org.opendaylight.nemo.user.vnspacemanager.instancecheck.ResultInstanceCheck;\r
+import org.opendaylight.nemo.user.vnspacemanager.syntaxcheck.ResultDefinitionCheck;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Results;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/8/31.\r
+ */\r
+public class UpdateResult {\r
+\r
+ private DataBroker dataBroker;\r
+ private TenantManage tenantManage;\r
+ private ResultDefinitionCheck resultDefinitionCheck;\r
+ private ResultInstanceCheck resultInstanceCheck;\r
+\r
+ public UpdateResult(DataBroker dataBroker, TenantManage tenantManage)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ this.tenantManage = tenantManage;\r
+ resultDefinitionCheck = new ResultDefinitionCheck();\r
+ resultInstanceCheck = new ResultInstanceCheck(tenantManage);\r
+ }\r
+\r
+ public String ResultHandling(UserId userId, Results results)\r
+ {\r
+ String errorDefinition = resultDefinitionCheck.CheckDefinition(results);\r
+ String errorInstance = resultInstanceCheck.checkResultInstance(userId,results);\r
+\r
+ if (errorDefinition!= null)\r
+ {\r
+ return errorDefinition;\r
+ }\r
+ else if (errorInstance != null)\r
+ {\r
+ return errorInstance;\r
+ }\r
+ else\r
+ {\r
+ //todo\r
+ }\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.syntaxcheck;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.PropertyName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.ConnectionDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.definitions.ConnectionDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.definitions.PropertyDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.instance.PropertyValues;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.common.RpcResult;\r
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import com.google.common.base.Optional;\r
+import com.google.common.base.Function;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class ConnectionDefinitionCheck {\r
+\r
+ private DataBroker dataBroker;\r
+ private List<ConnectionDefinition> connectionDefinitionList;\r
+ private static final Logger LOG = LoggerFactory.getLogger(ConnectionDefinitionCheck.class);\r
+\r
+ public ConnectionDefinitionCheck(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ connectionDefinitionList = null;\r
+ }\r
+\r
+ public String CheckConnectionDefinition(Connection connection)\r
+ {\r
+ fetchConnectionDefinitionList();\r
+ boolean ConnectionHasDefined = false;\r
+ String errorInfo = null;\r
+\r
+ if (connectionDefinitionList != null)\r
+ {\r
+ for (ConnectionDefinition connectionDefinition : connectionDefinitionList)\r
+ {\r
+ if (connectionDefinition.getConnectionType().equals(connection.getConnectionType()))\r
+ {\r
+ ConnectionHasDefined = true;\r
+ List<Property> connectionProperties = connection.getProperty();\r
+ List<PropertyDefinition> propertyDefinitions = connectionDefinition.getPropertyDefinition();\r
+\r
+ if (connectionProperties != null && propertyDefinitions ==null)\r
+ {\r
+ errorInfo = "There are no properties for this type of connection.";\r
+ break;\r
+ }\r
+ else if (connectionProperties != null && propertyDefinitions != null)\r
+ {\r
+ errorInfo = CheckProperty(connection.getProperty(), connectionDefinition.getPropertyDefinition());\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!ConnectionHasDefined)\r
+ {\r
+ return "This type of connection has not been defined.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private String CheckProperty(List<Property> connectionProperty, List<PropertyDefinition> propertyDefinitionList )\r
+ {\r
+ String errorInfo = null;\r
+ for (Property property : connectionProperty)\r
+ {\r
+ Boolean properyHasDefine = false;\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ for (PropertyDefinition propertyDefinition : propertyDefinitionList)\r
+ {\r
+ if (property.getPropertyName().equals(propertyDefinition.getPropertyName()))\r
+ {\r
+ properyHasDefine = true;\r
+ PropertyValues propertyValues = property.getPropertyValues();\r
+ PropertyDefinition.PropertyValueType propertyValueType = propertyDefinition.getPropertyValueType();\r
+\r
+ if (propertyValues != null && propertyValueType != null)\r
+ {\r
+ if (propertyDefinition.getIsReadOnly()!=null)\r
+ {\r
+ if (propertyDefinition.getIsRequired().getIntValue() == 1)\r
+ {\r
+ errorInfo = "The property value type of" + property.getPropertyName().toString() + "is read only.";\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (propertyValueType.getIntValue() == 0 && !(propertyValues.getIntValue() == null && propertyValues.getStringValue() != null && propertyValues.getRangeValue() == null)) {\r
+ errorInfo = "The property value type of" + property.getPropertyName().toString() + " should be string.";\r
+ break;\r
+ }\r
+ if (propertyValueType.getIntValue() == 1 && !(propertyValues.getIntValue() != null && propertyValues.getStringValue() == null && propertyValues.getRangeValue() == null)) {\r
+ errorInfo = "The property value type of" + property.getPropertyName().toString() + " should be integer.";\r
+ break;\r
+ }\r
+ if (propertyValueType.getIntValue() == 2 && !(propertyValues.getIntValue() == null && propertyValues.getStringValue() == null && propertyValues.getRangeValue() != null)) {\r
+ errorInfo = "The property value type of" + property.getPropertyName().toString() + " should be range.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (!properyHasDefine) {\r
+ errorInfo = "This type of property" + property.getPropertyName().toString() + " has not been defined.";\r
+ }\r
+ }\r
+ }\r
+\r
+ if (errorInfo == null)\r
+ {\r
+ Boolean requiredProperty = false;\r
+ for (PropertyDefinition propertyDefinition : propertyDefinitionList)\r
+ {\r
+ if (propertyDefinition.getIsRequired()!=null)\r
+ {\r
+ if (propertyDefinition.getIsRequired().getIntValue() == 0)\r
+ {\r
+ for (Property property : connectionProperty)\r
+ {\r
+ if (property.getPropertyName().equals(propertyDefinition.getPropertyName()))\r
+ {\r
+ requiredProperty = true;\r
+ }\r
+ }\r
+ if (!requiredProperty)\r
+ {\r
+ errorInfo = "The required property" + propertyDefinition.getPropertyName().toString() + "is not included in the intent.";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void fetchConnectionDefinitionList()\r
+ {\r
+ InstanceIdentifier<ConnectionDefinitions> connectiondefinitionId = InstanceIdentifier.builder(ConnectionDefinitions.class).build();\r
+ ListenableFuture<Optional<ConnectionDefinitions>> connectiondefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, connectiondefinitionId);\r
+ Futures.addCallback(connectiondefinitionFuture, new FutureCallback<Optional<ConnectionDefinitions>>() {\r
+ @Override\r
+ public void onSuccess(Optional<ConnectionDefinitions> result) {\r
+ setConnectionDefinitionList(result.get().getConnectionDefinition());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Can not read connection definition information.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ return;\r
+ }\r
+\r
+ private void setConnectionDefinitionList(List<ConnectionDefinition> connectionDefinitionList)\r
+ {\r
+ this.connectionDefinitionList = connectionDefinitionList;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.syntaxcheck;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.FlowPropertyDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.MatchItemDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.flow.instance.MatchItem;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.match.item.definitions.MatchItemDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.match.item.instance.MatchItemValue;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.common.RpcResult;\r
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import com.google.common.base.Optional;\r
+import com.google.common.base.Function;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class FlowDefinitionCheck {\r
+\r
+ private DataBroker dataBroker;\r
+ private List<MatchItemDefinition> matchItemDefinitionList;\r
+ private static final Logger LOG = LoggerFactory.getLogger(FlowDefinitionCheck.class);\r
+\r
+ public FlowDefinitionCheck(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ matchItemDefinitionList = null;\r
+ }\r
+\r
+ public String CheckDefinition(Flow flow)\r
+ {\r
+ String errorInfo = null;\r
+ fetchMatchItemDefinitions();\r
+ Boolean matchHasDefined = false;\r
+ if (flow.getMatchItem() != null)\r
+ {\r
+ if (matchItemDefinitionList != null )\r
+ {\r
+ for (MatchItem matchItem : flow.getMatchItem())\r
+ {\r
+ for (MatchItemDefinition matchItemDefinition : matchItemDefinitionList)\r
+ {\r
+ if (matchItem.getMatchItemName().equals(matchItemDefinition.getMatchItemName()))\r
+ {\r
+ matchHasDefined = true;\r
+ MatchItemValue matchItemValue = matchItem.getMatchItemValue();\r
+ MatchItemDefinition.MatchItemValueType matchItemValueType = matchItemDefinition.getMatchItemValueType();\r
+\r
+ if (matchItemValue != null && matchItemValueType != null)\r
+ {\r
+ if (matchItemValueType.getIntValue()==0 && !(matchItemValue.getIntValue()==null&&matchItemValue.getStringValue()!=null&&matchItemValue.getRangeValue()==null))\r
+ {\r
+ errorInfo = "The match item value type for" +matchItem.getMatchItemName().toString()+"should be string.";\r
+ break;\r
+ }\r
+\r
+ if (matchItemValueType.getIntValue()==1 && !(matchItemValue.getIntValue()!=null&&matchItemValue.getStringValue()==null&&matchItemValue.getRangeValue()==null))\r
+ {\r
+ errorInfo = "The match item value type for" + matchItem.getMatchItemName().toString()+"should be integer.";\r
+ break;\r
+ }\r
+\r
+ if (matchItemValueType.getIntValue()==2 && !(matchItemValue.getIntValue()==null&&matchItemValue.getStringValue()==null&&matchItemValue.getRangeValue()!=null))\r
+ {\r
+ errorInfo = "The match item value type for" + matchItem.getMatchItemName().toString()+"should be range.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (!matchHasDefined)\r
+ {\r
+ errorInfo = "The match item has not been defined.";\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void fetchMatchItemDefinitions()\r
+ {\r
+ InstanceIdentifier<MatchItemDefinitions> matchitemdefinitionId = InstanceIdentifier.builder(MatchItemDefinitions.class).build();\r
+ ListenableFuture<Optional<MatchItemDefinitions>> matchitemdefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, matchitemdefinitionId);\r
+ Futures.addCallback(matchitemdefinitionFuture, new FutureCallback<Optional<MatchItemDefinitions>>() {\r
+ @Override\r
+ public void onSuccess(Optional<MatchItemDefinitions> result) {\r
+ setMatchItemDefinitionList( result.get().getMatchItemDefinition());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Can not read match item definition information.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ return ;\r
+ }\r
+\r
+ private void setMatchItemDefinitionList(List<MatchItemDefinition> matchItemDefinitionList)\r
+ {\r
+ this.matchItemDefinitionList = matchItemDefinitionList;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.syntaxcheck;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.PropertyName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.NodeDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.definitions.NodeDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.Property;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.definitions.PropertyDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.instance.PropertyValues;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.yang.common.RpcResult;\r
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import com.google.common.base.Optional;\r
+import com.google.common.base.Function;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class NodeDefinitionCheck {\r
+\r
+ private DataBroker dataBroker;\r
+ private List<NodeDefinition> nodeDefinitionList;\r
+ private static final Logger LOG = LoggerFactory.getLogger(NodeDefinitionCheck.class);\r
+\r
+ public NodeDefinitionCheck(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ nodeDefinitionList = null;\r
+ }\r
+\r
+ public String CheckNodeDefinition(Node node)\r
+ {\r
+ String errorInfo = null;\r
+ Boolean NodeHasDefined = false;\r
+\r
+ fetchNodeDefinitions();\r
+ if (nodeDefinitionList != null)\r
+ {\r
+ for (NodeDefinition nodeDefinition : nodeDefinitionList)\r
+ {\r
+ if (nodeDefinition.getNodeType().equals(node.getNodeType()))\r
+ {\r
+ NodeHasDefined = true;\r
+ List<Property> nodeProperties = node.getProperty();\r
+ List<PropertyDefinition> nodePropertyDefinitions = nodeDefinition.getPropertyDefinition();\r
+\r
+ if (nodeProperties != null && nodePropertyDefinitions == null)\r
+ {\r
+ errorInfo = "This type of node has no properties.";\r
+ break;\r
+ }\r
+ else if (nodeProperties != null && nodePropertyDefinitions != null)\r
+ {\r
+ errorInfo = checkProperty(nodeProperties, nodeDefinition.getPropertyDefinition());\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!NodeHasDefined)\r
+ {\r
+ errorInfo = "This type of Node has not been defined.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private String checkProperty(List<Property> nodeProperties, List<PropertyDefinition> nodePropertyDefinitions)\r
+ {\r
+ Boolean propertyHasDefine = false;\r
+ String errorInfo = null;\r
+\r
+ for (Property property : nodeProperties)\r
+ {\r
+ if (errorInfo != null)\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ for (PropertyDefinition propertydefinition : nodePropertyDefinitions)\r
+ {\r
+ if (property.getPropertyName().equals(propertydefinition.getPropertyName()))\r
+ {\r
+ propertyHasDefine = true;\r
+ PropertyValues propertyValues = property.getPropertyValues();\r
+ PropertyDefinition.PropertyValueType propertyValueType = propertydefinition.getPropertyValueType();\r
+\r
+ if (propertyValues != null && propertyValueType != null)\r
+ {\r
+ if (propertydefinition.getIsReadOnly()!=null)\r
+ {\r
+ if (propertydefinition.getIsRequired().getIntValue() == 1)\r
+ {\r
+ errorInfo = "The property"+ property.getPropertyName().toString()+" is readonly, can not be written.";\r
+ break;\r
+ }\r
+ }\r
+ else if (propertyValueType.getIntValue() == 0 && !(propertyValues.getIntValue() == null && propertyValues.getStringValue() != null && propertyValues.getRangeValue() == null))\r
+ {\r
+ errorInfo = "The property value type"+property.getPropertyName().toString()+" should be string";\r
+ break;\r
+ }\r
+ else if (propertyValueType.getIntValue() == 1 && !(propertyValues.getIntValue() != null && propertyValues.getStringValue() == null && propertyValues.getRangeValue() == null))\r
+ {\r
+ errorInfo = "The property value type"+property.getPropertyName().toString()+" should be integer";\r
+ break;\r
+ }\r
+ else if (propertyValueType.getIntValue() == 2 && !(propertyValues.getIntValue() == null && propertyValues.getStringValue() == null && propertyValues.getRangeValue() != null))\r
+ {\r
+ errorInfo = "The property value type"+property.getPropertyName().toString()+" should be range";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!propertyHasDefine)\r
+ {\r
+ errorInfo = "The property"+property.getPropertyName().toString()+"has not been defined.";\r
+ }\r
+ }\r
+ }\r
+\r
+ if (errorInfo == null)\r
+ {\r
+ Boolean requiredProperty = false;\r
+ for (PropertyDefinition propertyDefinition : nodePropertyDefinitions)\r
+ {\r
+ if (propertyDefinition.getIsRequired()!=null)\r
+ {\r
+ if (propertyDefinition.getIsRequired().getIntValue() ==0)\r
+ {\r
+ for (Property property: nodeProperties)\r
+ {\r
+ if (property.getPropertyName().equals(propertyDefinition.getPropertyName()))\r
+ {\r
+ requiredProperty = true;\r
+ }\r
+ }\r
+ if (!requiredProperty)\r
+ {\r
+ errorInfo = "The required property "+ propertyDefinition.getPropertyName().toString() + "is not included in the intent.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void fetchNodeDefinitions()\r
+ {\r
+ InstanceIdentifier<NodeDefinitions> nodedefinitionId = InstanceIdentifier.builder(NodeDefinitions.class).build();\r
+ ListenableFuture<Optional<NodeDefinitions>> nodedefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, nodedefinitionId);\r
+ Futures.addCallback(nodedefinitionFuture, new FutureCallback<Optional<NodeDefinitions>>() {\r
+ @Override\r
+ public void onSuccess(Optional<NodeDefinitions> result)\r
+ {\r
+ setNodeDefinitionList(result.get().getNodeDefinition());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t)\r
+ {\r
+ LOG.error("Can not read node definitions information.", t);\r
+ return;\r
+ }\r
+ });\r
+ return ;\r
+ }\r
+\r
+ private void setNodeDefinitionList(List<NodeDefinition> nodeDefinitionsList)\r
+ {\r
+ this.nodeDefinitionList = nodeDefinitionsList;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.syntaxcheck;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+import com.google.common.util.concurrent.ListenableFuture;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ParameterName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.ActionDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.ConditionParameterDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.action.definitions.ActionDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.action.instance.ParameterValues;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.instance.ConditionSegment;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.instance.condition.segment.ConditionParameterTargetValue;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.parameter.definitions.ConditionParameterDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.parameter.definitions.condition.parameter.definition.ParameterMatchPatterns;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.operation.instance.Action;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class OperationDefinitionCheck {\r
+\r
+ private DataBroker dataBroker;\r
+ private List<ActionDefinition> actionDefinitionList;\r
+ private List<ConditionParameterDefinition> conditionParameterDefinitionList;\r
+ private static final Logger LOG = LoggerFactory.getLogger(OperationDefinitionCheck.class);\r
+ public OperationDefinitionCheck(DataBroker dataBroker)\r
+ {\r
+ this.dataBroker = dataBroker;\r
+ actionDefinitionList = null;\r
+ conditionParameterDefinitionList = null;\r
+ }\r
+\r
+ public String CheckDefinition(Operation operation)\r
+ {\r
+ fetchActionDefinitions();\r
+ fetchConditionParaDefinitions();\r
+ String errorInfo = null;\r
+\r
+ if (operation.getAction() != null )\r
+ {\r
+ errorInfo = checkAction(operation);\r
+ }\r
+ if (errorInfo == null && operation.getConditionSegment() != null)\r
+ {\r
+ errorInfo = checkCondition(operation);\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private String checkAction(Operation operation)\r
+ {\r
+ String errorInfo = null;\r
+ Boolean actionHasDefine = false;\r
+\r
+ if ( actionDefinitionList == null)\r
+ {\r
+ errorInfo = "There are no actions has been defined in the data store.";\r
+ }\r
+ else {\r
+ for (Action action : operation.getAction()) {\r
+ for (ActionDefinition actionDefinition : actionDefinitionList) {\r
+ if (actionDefinition.getActionName().equals(action.getActionName())) {\r
+ actionHasDefine = true;\r
+\r
+ ParameterValues parameterValues = action.getParameterValues();\r
+ ActionDefinition.ParameterValueType parameterValueType = actionDefinition.getParameterValueType();\r
+\r
+ if (parameterValues != null && parameterValueType != null)\r
+ {\r
+ if (parameterValueType.getIntValue() == 0 && !(parameterValues.getIntValue() == null && parameterValues.getStringValue() != null && parameterValues.getRangeValue() == null)) {\r
+ errorInfo = "The value type of" + action.getActionName().toString() + "should be string.";\r
+ break;\r
+ }\r
+ if (parameterValueType.getIntValue() == 1 && !(parameterValues.getIntValue() != null && parameterValues.getStringValue() == null && parameterValues.getRangeValue() == null)) {\r
+ errorInfo = "The value type of" + action.getActionName().toString() + "should be integer.";\r
+ break;\r
+ }\r
+ if (parameterValueType.getIntValue() == 2 && !(parameterValues.getIntValue() == null && parameterValues.getStringValue() == null && parameterValues.getRangeValue() != null)) {\r
+ errorInfo = "The value type of" + action.getActionName().toString() + "should be range.";\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+ if (!actionHasDefine) {\r
+ errorInfo = "The action type has not been defined.";\r
+ }\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private String checkCondition(Operation operation)\r
+ {\r
+ String errorInfo = null;\r
+ Boolean conditionHasDefined = false;\r
+\r
+ if (conditionParameterDefinitionList != null)\r
+ {\r
+ if (operation.getConditionSegment() != null)\r
+ {\r
+ for (ConditionSegment conditionSegment :operation.getConditionSegment())\r
+ {\r
+ for (ConditionParameterDefinition conditionParameterDefinition : conditionParameterDefinitionList)\r
+ {\r
+ if (conditionParameterDefinition.getParameterName().getValue().equals(conditionSegment.getConditionParameterName().getValue()))\r
+ {\r
+ conditionHasDefined = true;\r
+ if (conditionSegment.getConditionParameterMatchPattern() != null)\r
+ {\r
+ if (conditionParameterDefinition.getParameterMatchPatterns() != null)\r
+ {\r
+ List<ParameterMatchPatterns.ParameterMatchPattern> conditionParameterMatchPatterns = conditionParameterDefinition.getParameterMatchPatterns().getParameterMatchPattern();\r
+ if (conditionParameterMatchPatterns != null)\r
+ {\r
+ Boolean matchpatternexist = false;\r
+ for (ParameterMatchPatterns.ParameterMatchPattern parameterMatchPattern : conditionParameterMatchPatterns)\r
+ {\r
+ if (parameterMatchPattern.getIntValue() == conditionSegment.getConditionParameterMatchPattern().getIntValue())\r
+ {\r
+ matchpatternexist = true;\r
+ break;\r
+ }\r
+ }\r
+ if (!matchpatternexist)\r
+ {\r
+ errorInfo = "The match pattern has not defined in the condition.";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "There are no match pattern in match pattrn list.";\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ errorInfo = "No match patterns have been defined in data store.";\r
+ break;\r
+ }\r
+ }\r
+ if (conditionSegment.getConditionParameterTargetValue() != null)\r
+ {\r
+ if (conditionParameterDefinition.getParameterValueType() != null)\r
+ {\r
+ ConditionParameterTargetValue conditionParameterTargetValue = conditionSegment.getConditionParameterTargetValue();\r
+ ConditionParameterDefinition.ParameterValueType parameterValueType = conditionParameterDefinition.getParameterValueType();\r
+\r
+ if (parameterValueType.getIntValue() == 0 && !(conditionParameterTargetValue.getIntValue() == null && conditionParameterTargetValue.getStringValue() != null && conditionParameterTargetValue.getRangeValue() == null)) {\r
+ errorInfo = "The value type of" + conditionSegment.getConditionParameterName().toString() + "should be string.";\r
+ break;\r
+ }\r
+ if (parameterValueType.getIntValue() == 1 && !(conditionParameterTargetValue.getIntValue() != null && conditionParameterTargetValue.getStringValue() == null && conditionParameterTargetValue.getRangeValue() == null)) {\r
+ errorInfo = "The value type of" + conditionSegment.getConditionParameterName().toString() + "should be integer.";\r
+ break;\r
+ }\r
+ if (parameterValueType.getIntValue() == 2 && !(conditionParameterTargetValue.getIntValue() == null && conditionParameterTargetValue.getStringValue() == null && conditionParameterTargetValue.getRangeValue() != null)) {\r
+ errorInfo = "The value type of" + conditionSegment.getConditionParameterName().toString() + "should be range.";\r
+ break;\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!conditionHasDefined)\r
+ {\r
+ errorInfo = "This condition has not been defined in data store.";\r
+ }\r
+ return errorInfo;\r
+ }\r
+\r
+ private void fetchActionDefinitions()\r
+ {\r
+ InstanceIdentifier<ActionDefinitions> actiondefinitionId = InstanceIdentifier.builder(ActionDefinitions.class).build();\r
+ ListenableFuture<Optional<ActionDefinitions>> actiondefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, actiondefinitionId);\r
+ Futures.addCallback(actiondefinitionFuture, new FutureCallback<Optional<ActionDefinitions>>() {\r
+ @Override\r
+ public void onSuccess(Optional<ActionDefinitions> result) {\r
+ setActionDefinitionList( result.get().getActionDefinition());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Can not read action definition information.", t);\r
+\r
+ return;\r
+ }\r
+ });\r
+ return ;\r
+ }\r
+\r
+ private void fetchConditionParaDefinitions()\r
+ {\r
+ InstanceIdentifier<ConditionParameterDefinitions> conditionparadefinitionId = InstanceIdentifier.builder(ConditionParameterDefinitions.class).build();\r
+ ListenableFuture<Optional<ConditionParameterDefinitions>> conditionparadefinitionFuture = dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.CONFIGURATION, conditionparadefinitionId);\r
+ Futures.addCallback(conditionparadefinitionFuture, new FutureCallback<Optional<ConditionParameterDefinitions>>() {\r
+ @Override\r
+ public void onSuccess(Optional<ConditionParameterDefinitions> result) {\r
+ setConditionParameterDefinitionList( result.get().getConditionParameterDefinition());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void onFailure(Throwable t) {\r
+ LOG.error("Can not read condition parameter definition information.", t);\r
+ return;\r
+ }\r
+ });\r
+ return ;\r
+ }\r
+\r
+ private void setActionDefinitionList(List<ActionDefinition> actionDefinitionList)\r
+ {\r
+ this.actionDefinitionList = actionDefinitionList;\r
+ }\r
+\r
+ private void setConditionParameterDefinitionList(List<ConditionParameterDefinition> conditionParameterDefinitionList)\r
+ {\r
+ this.conditionParameterDefinitionList = conditionParameterDefinitionList;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.user.vnspacemanager.syntaxcheck;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Results;\r
+\r
+/**\r
+ * Created by z00293636 on 2015/9/2.\r
+ */\r
+public class ResultDefinitionCheck {\r
+\r
+ public String CheckDefinition(Results results)\r
+ {\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.impl.rev151010;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.nemo.intent.IntentResolver;
+import org.opendaylight.nemo.user.UserManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NemoEngineModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.impl.rev151010.AbstractNemoEngineModule {
+ private static final Logger LOG = LoggerFactory.getLogger(NemoEngineModule.class);
+
+ public NemoEngineModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public NemoEngineModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, NemoEngineModule oldModule, AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public AutoCloseable createInstance() {
+ DataBroker dataBroker = getDataBrokerDependency();
+ RpcProviderRegistry rpcProviderRegistry = getRpcRegistryDependency();
+
+ final IntentResolver intentResolver = new IntentResolver(dataBroker);
+ final UserManager userManager = new UserManager(dataBroker, rpcProviderRegistry, intentResolver);
+
+ final class NemoEngine implements AutoCloseable {
+ @Override
+ public void close() throws Exception {
+ if ( null != intentResolver ) {
+ intentResolver.close();
+ }
+
+ if ( null != userManager ) {
+ userManager.close();
+ }
+
+ return;
+ }
+ }
+
+ LOG.info("Initialized the NEMO engine.");
+
+ return new NemoEngine();
+ }
+
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: nemo-engine-impl yang module local name: nemo-engine-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Sep 02 22:15:04 CST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.impl.rev151010;
+public class NemoEngineModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.impl.rev151010.AbstractNemoEngineModuleFactory {
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+Copyright (c) 2015 Huawei, Inc and others. All rights reserved.\r
+This program and the accompanying materials are made available under the\r
+terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+and is available at http://www.eclipse.org/legal/epl-v10.html\r
+-->\r
+<snapshot>\r
+ <configuration>\r
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">\r
+ <module>\r
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:nemo:engine:impl">prefix:nemo-engine-impl</type>\r
+ <name>nemo-engine-impl</name>\r
+ <data-broker>\r
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>\r
+ <name>binding-data-broker</name>\r
+ </data-broker>\r
+ <rpc-registry>\r
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>\r
+ <name>binding-rpc-broker</name>\r
+ </rpc-registry>\r
+ </module>\r
+ </modules>\r
+ </data>\r
+ </configuration>\r
+\r
+ <required-capabilities></required-capabilities>\r
+</snapshot>
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python
+#Filename:nemo-odl.py
+import requests,json
+import argparse, sys
+from requests.auth import HTTPBasicAuth
+
+USERNAME='admin'
+PASSWORD='admin'
+
+PREDEFINE_USERROLE="http://%s:8181/restconf/config/nemo-user:user-roles/"
+PREDEFINE_NODETYPE="http://%s:8181/restconf/config/nemo-object:node-definitions/"
+PREDEFINE_CONNECTIONTYPE="http://%s:8181/restconf/config/nemo-object:connection-definitions/"
+PREDEFINE_FLOWMATCHTYPE="http://%s:8181/restconf/config/nemo-object:match-item-definitions/"
+PREDEFINE_FLOWPROPERTY="http://%s:8181/restconf/config/nemo-object:flow-property-definitions/"
+PREDEFINE_OPERATIONACTION="http://%s:8181/restconf/config/nemo-operation:action-definitions/"
+PREDEFINE_OPERATIONCONDITION="http://%s:8181/restconf/config/nemo-operation:condition-parameter-definitions/"
+PHYSICAL_PORT_ATTRIBUTE="http://%s:8181/restconf/config/generic-physical-network:physical-port-attribute-definitions/"
+PHYSICAL_NODE_ATTRIBUTE="http://%s:8181/restconf/config/generic-physical-network:physical-node-attribute-definitions/"
+
+
+
+def add_predefined_userrole(contHost):
+ data={
+ "user-roles": {
+ "user-role": [
+ {
+ "role-name": "tenant",
+ "role-description": "It's a non-administor user"
+ }
+ ]
+ }
+ }
+ put(PREDEFINE_USERROLE % contHost, data)
+
+def add_predefined_nodetypes(contHost):
+ data={
+ "node-definitions": {
+ "node-definition": [
+ {
+ "node-type": "host",
+ "property-definition": [
+ {
+ "property-name": "name",
+ "property-value-type": "string"
+ },
+ {
+ "property-name": "location",
+ "property-value-type": "string"
+ },
+ {
+ #For example, one legal mac-address is 00:01:0a:90:78:02.
+ "property-name": "mac-address",
+ "property-value-type": "string"
+ },
+ {
+ #For example, one legal ip-address is 10.0.2.0/24.
+ "property-name": "ip-address",
+ "property-value-type": "string"
+ }
+ ]
+ },
+ {
+ "node-type": "l2-group",
+ "property-definition": [
+ {
+ #For example, one legal ip-address is 10.0.2.0/24.
+ "property-name": "ip-prefix",
+ "property-value-type": "string"
+ },
+ {
+ #For example, one legal gateway-ip is 10.0.2.1.
+ "property-name": "gateway-ip",
+ "property-value-type": "string"
+ },
+ {
+ "property-name": "location",
+ "property-value-type": "string"
+ }
+ ]
+ },
+ {
+ "node-type": "l3-group",
+ "property-definition": [
+ {
+ #For example, one legal ip-address is 10.0.2.0/24.
+ "property-name": "ip-prefix",
+ "property-value-type": "string"
+ }
+ ]
+ },
+ {
+ "node-type": "ext-group",
+ "property-definition": [
+ {
+ "property-name": "location",
+ "property-value-type": "string",
+ "is-required": "required"
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-value-type": "string",
+ "is-required": "required"
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-value-type": "string",
+ "is-required": "required"
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-value-type": "string"
+ }
+ ]
+ },
+ {
+ "node-type": "chain-group"
+ },
+ {
+ "node-type": "fw",
+ "property-definition": [
+ {
+ "property-name": "location",
+ "property-value-type": "string",
+ "is-required": "required"
+ },
+ {
+ "property-name": "operating-mode",
+ "property-value-type": "string",
+ "is-required": "required"
+ }
+ ]
+ },
+ {
+ "node-type": "lb",
+ "property-definition": [
+ {
+ "property-name": "location",
+ "property-value-type": "string",
+ "is-required": "required"
+ },
+ {
+ "property-name": "operating-mode",
+ "property-value-type": "string",
+ "is-required": "required"
+ }
+ ]
+ },
+ {
+ "node-type": "cache",
+ "property-definition": [
+ {
+ "property-name": "location",
+ "property-value-type": "string",
+ "is-required": "required"
+ },
+ {
+ "property-name": "operating-mode",
+ "property-value-type": "string",
+ "is-required": "required"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ put(PREDEFINE_NODETYPE % contHost, data)
+
+def add_predefined_connectiontypes(contHost):
+ data={
+ "connection-definitions": {
+ "connection-definition":[
+ {
+ "connection-type": "p2p",
+ "property-definition": [
+ {
+ #the unit of bandwidth is mbps.
+ "property-name": "bandwidth",
+ "property-value-type": "int"
+ }
+ ]
+ },
+ {
+ "connection-type": "p2mp",
+ "property-definition": [
+ {
+ #the unit of bandwidth is mbps.
+ "property-name": "bandwidth",
+ "property-value-type": "int"
+ }
+ ]
+ },
+ {
+ "connection-type": "mesh",
+ "property-definition": [
+ {
+ #the unit of bandwidth is mbps.
+ "property-name": "bandwidth",
+ "property-value-type": "int"
+ }
+ ]
+ },
+ {
+ "connection-type": "chain",
+ "property-definition": [
+ {
+ #the unit of bandwidth is mbps.
+ "property-name": "bandwidth",
+ "property-value-type": "int"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ put(PREDEFINE_CONNECTIONTYPE % contHost, data)
+
+def add_flow_matchtypes(contHost):
+ data={
+ "match-item-definitions": {
+ "match-item-definition": [
+ {
+ #For example, one legal eth-type is arp.
+ "match-item-name": "eth-type",
+ "match-item-value-type": "string"
+ },
+ {
+ #For example, one legal src-mac is 00:00:0a:b7:01:90;
+ "match-item-name": "src-mac",
+ "match-item-value-type": "string"
+ },
+ {
+ #For example, one legal src-mac is 00:00:0a:b7:01:90;
+ "match-item-name": "dst-mac",
+ "match-item-value-type": "string"
+ },
+ {
+ #For example, one legal proto is http;
+ "match-item-name": "proto",
+ "match-item-value-type": "string"
+ },
+ {
+ #For example, one legal src-ip is 10.0.2.1;
+ "match-item-name": "src-ip",
+ "match-item-value-type": "string"
+ },
+ {
+ #For example, one legal dst-ip is 10.0.1.2;
+ "match-item-name": "dst-ip",
+ "match-item-value-type": "string"
+ },
+ {
+ #For example, one legal src-port is 80;
+ "match-item-name": "src-port",
+ "match-item-value-type": "int"
+ },
+ {
+ #For example, one legal dst-port is 22;
+ "match-item-name": "dst-port",
+ "match-item-value-type": "int"
+ }
+ ]
+ }
+ }
+ put(PREDEFINE_FLOWMATCHTYPE % contHost, data)
+
+def add_flow_properties(contHost):
+ data={
+ "flow-property-definitions": {
+ "property-definition": [
+ {
+ "property-name": "path",
+ "property-value-type": "string"
+ }
+ ]
+ }
+ }
+ put(PREDEFINE_FLOWPROPERTY % contHost, data)
+
+def add_operation_actions(contHost):
+ data={
+ "action-definitions": {
+ "action-definition": [
+ {
+ "action-name": "deny"
+ },
+ {
+ "action-name": "allow"
+ },
+ {
+ "action-name": "go-through",
+ "parameter-value-type": "string"
+ },
+ {
+ "action-name": "qos-bandwidth",
+ "parameter-value-type": "int"
+ }
+ ]
+ }
+ }
+ put(PREDEFINE_OPERATIONACTION % contHost, data)
+
+def add_operation_conditions(contHost):
+ data={
+ "condition-parameter-definitions": {
+ "condition-parameter-definition": [
+ {
+ "parameter-name": "time",
+ "parameter-value-type": "string",
+ "parameter-match-patterns": {
+ "parameter-match-pattern": ["less-than" ,"not-less-than","equal","not-equal",
+ "greater-than","not-greater-than","between","periodical"]
+ } }
+ ]
+ }
+ }
+ put(PREDEFINE_OPERATIONCONDITION % contHost, data)
+
+def add_port_attributes(conHost):
+ data={
+ "physical-port-attribute-definitions":{
+ "physical-port-attribute-definition":[
+ {
+ "attribute-name":"location",
+ "attribute-value-type":"string",
+ "attribute-match-patterns":{
+ "attribute-match-pattern":["equal"]
+ }
+ }
+ ]
+ }
+ }
+ put(PHYSICAL_PORT_ATTRIBUTE % conHost, data)
+
+def add_node_attributes(conHost):
+ data={
+ "physical-node-attribute-definitions":{
+ "physical-node-attribute-definition":[
+ {
+ "attribute-name":"location",
+ "attribute-value-type":"string",
+ "attribute-match-patterns":{
+ "attribute-match-pattern":["equal"]
+ }
+ },
+ {
+ "attribute-name":"capacity",
+ "attribute-value-type":"int",
+ "attribute-match-patterns":{
+ "attribute-match-pattern":["equal"]
+ }
+ }
+ ]
+ }
+ }
+ put(PHYSICAL_NODE_ATTRIBUTE % conHost, data)
+
+
+
+def put(url, data):
+ headers = {'Content-type': 'application/yang.data+json',
+ 'Accept': 'application/yang.data+json'}
+ print "PUT %s" % url
+ print json.dumps(data, indent=4, sort_keys=True)
+ r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ print r.text
+ r.raise_for_status()
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--controller', default='127.0.0.1', help='controller IP')
+ args=parser.parse_args()
+
+ print args.controller
+
+ add_predefined_userrole(args.controller)
+ add_predefined_nodetypes(args.controller)
+ add_predefined_connectiontypes(args.controller)
+ add_flow_matchtypes(args.controller)
+ add_flow_properties(args.controller)
+ add_operation_actions(args.controller)
+ add_operation_conditions(args.controller)
+ add_port_attributes(args.controller)
+ add_node_attributes(args.controller)
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module generic-physical-network {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:generic:physical:network";\r
+ prefix "generic-pn";\r
+\r
+ import nemo-engine-common {prefix nemo-engine-common;}\r
+ import ietf-inet-types {\r
+ prefix inet;\r
+ revision-date 2010-09-24;\r
+ }\r
+ import ietf-yang-types {\r
+ prefix yang;\r
+ revision-date 2010-09-24;\r
+ }\r
+\r
+ description\r
+ "Represents the generic physical network information model.\r
+ Each renderer will collect detailed physical network information\r
+ and fill in this generic model.";\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ grouping attribute-definition {\r
+ description\r
+ "Defines an attribute for a physical port or node.";\r
+\r
+ leaf attribute-name {\r
+ description\r
+ "A name for the attribute.";\r
+ type nemo-engine-common:attribute-name;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf attribute-value-type {\r
+ description\r
+ "The value type for the attribute.";\r
+ type enumeration {\r
+ enum string;\r
+ enum int;\r
+ enum range;\r
+ }\r
+ }\r
+\r
+ container attribute-match-patterns {\r
+ description\r
+ "Defines the match patterns of the attribute.";\r
+\r
+ leaf-list attribute-match-pattern {\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ container physical-port-attribute-definitions {\r
+ description\r
+ "Contains all attribute definitions for the physical port.";\r
+\r
+ list physical-port-attribute-definition {\r
+ description\r
+ "An attribute definition for the physical port.";\r
+\r
+ key "attribute-name";\r
+ uses attribute-definition;\r
+ }\r
+ }\r
+\r
+ container physical-node-attribute-definitions {\r
+ description\r
+ "Contains all attribute definitions for the physical node.";\r
+\r
+ list physical-node-attribute-definition {\r
+ description\r
+ "An attribute definition for the physical node.";\r
+\r
+ key "attribute-name";\r
+ uses attribute-definition;\r
+ }\r
+ }\r
+\r
+ grouping attribute-instance {\r
+ description\r
+ "Represents an attribute instance and it's metadata.";\r
+\r
+ leaf attribute-name {\r
+ description\r
+ "A name for an attribute instance.";\r
+ type nemo-engine-common:attribute-name;\r
+ mandatory true;\r
+ }\r
+\r
+ container attribute-value {\r
+ description\r
+ "The value of the attribute instance.";\r
+\r
+ leaf string-value {\r
+ type string;\r
+ }\r
+\r
+ leaf int-value {\r
+ type int64;\r
+ }\r
+\r
+ container range-value {\r
+ leaf min {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf max {\r
+ type int64;\r
+ mandatory true;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping physical-port-instance {\r
+ description\r
+ "Represents a physical port instance and it's metadata.";\r
+\r
+ leaf port-id {\r
+ description\r
+ "A unique ID for a physical port.";\r
+ type nemo-engine-common:physical-port-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf port-type {\r
+ description\r
+ "The type of a physical port.";\r
+ type enumeration {\r
+ enum external {\r
+ description\r
+ "The physical port is connected to a external host\r
+ or network device.";\r
+ }\r
+ enum internal {\r
+ description\r
+ "The physical port is connected to a physical node.";\r
+ }\r
+ }\r
+ mandatory true;\r
+ }\r
+\r
+ leaf mac-address {\r
+ description\r
+ "The mac address of a physical port.";\r
+ type yang:mac-address;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf bandwidth {\r
+ description\r
+ "The bandwidth capacity of a physical port.\r
+ The unit is kbps.";\r
+ type uint32;\r
+ units kbps;\r
+ }\r
+\r
+ list attribute {\r
+ description\r
+ "The list of attributes of a physical port.";\r
+\r
+ key "attribute-name";\r
+ uses attribute-instance;\r
+ }\r
+ }\r
+\r
+ grouping physical-node-instance {\r
+ description\r
+ "Represents a physical node instance and it's metadata.";\r
+\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for a physical node.";\r
+ type nemo-engine-common:physical-node-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf node-type {\r
+ description\r
+ "The type of a physical node.";\r
+ type enumeration {\r
+ enum switch;\r
+ enum router;\r
+ enum firewall;\r
+ enum loadbalancer;\r
+ }\r
+ }\r
+\r
+ list physical-port {\r
+ description\r
+ "The list of ports of a physical node.";\r
+\r
+ key "port-id";\r
+ uses physical-port-instance;\r
+ }\r
+\r
+ list attribute {\r
+ description\r
+ "The list of attributes of a physical node.";\r
+\r
+ key "attribute-name";\r
+ uses attribute-instance;\r
+ }\r
+ }\r
+\r
+ grouping physical-link-instance {\r
+ description\r
+ "Represents a physical link instance and it's metadata.";\r
+\r
+ leaf link-id {\r
+ description\r
+ "A unique ID for a physical link.";\r
+ type nemo-engine-common:physical-link-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf src-node-id {\r
+ description\r
+ "Represents the ID of the source physical node.";\r
+ type nemo-engine-common:physical-node-id;\r
+ }\r
+\r
+ leaf src-port-id {\r
+ description\r
+ "Represents the ID of the source physical port.";\r
+ type nemo-engine-common:physical-port-id;\r
+ }\r
+\r
+ leaf dest-node-id {\r
+ description\r
+ "Represents the ID of the destination physical node.";\r
+ type nemo-engine-common:physical-node-id;\r
+ }\r
+\r
+ leaf dest-port-id {\r
+ description\r
+ "Represents the ID of the destination physical port.";\r
+ type nemo-engine-common:physical-port-id;\r
+ }\r
+\r
+ leaf metric {\r
+ description\r
+ "The routing metric is used by routing computation.";\r
+ type uint32;\r
+ }\r
+\r
+ leaf bandwidth {\r
+ description\r
+ "The bandwidth capacity of a physical link.\r
+ The unit is kbps.";\r
+ type uint32;\r
+ units kbps;\r
+ }\r
+\r
+ leaf delay {\r
+ description\r
+ "The packet transfer delay of a physical link.\r
+ The unit is millisecond.";\r
+ type uint32;\r
+ units millisecond;\r
+ }\r
+\r
+ leaf loss-rate {\r
+ description\r
+ "The ratio of total lost packet outcomes to\r
+ total transmitted packets. The unit is percent.";\r
+ type uint8 {\r
+ range "0..100";\r
+ }\r
+ units percent;\r
+ }\r
+ }\r
+\r
+ grouping physical-host-instance {\r
+ description\r
+ "Represents a physical host instance and it's metadata.";\r
+\r
+ leaf host-id {\r
+ description\r
+ "A unique ID for a physical host.";\r
+ type nemo-engine-common:physical-host-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf host-name {\r
+ description\r
+ "A human-readable name for a physical host.";\r
+ type nemo-engine-common:physical-host-name;\r
+ }\r
+\r
+ leaf mac-address {\r
+ description\r
+ "The mac address of the host.";\r
+ type yang:mac-address;\r
+ mandatory true;\r
+ }\r
+\r
+ container ip-addresses {\r
+ description\r
+ "One or more ip addresses of the host.";\r
+\r
+ leaf-list ip-address {\r
+ type inet:ip-address;\r
+ min-elements 1;\r
+ }\r
+ }\r
+\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for the physical node that the host connects to.";\r
+ type nemo-engine-common:physical-node-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf port-id {\r
+ description\r
+ "A unique ID for the physical port that the host connects to.";\r
+ type nemo-engine-common:physical-port-id;\r
+ mandatory true;\r
+ }\r
+ }\r
+\r
+ grouping physical-path-instance {\r
+ description\r
+ "Represents a physical tunnel instance and it's metadata.";\r
+\r
+ leaf path-id {\r
+ description\r
+ "A unique ID for a physical path.";\r
+ type nemo-engine-common:physical-path-id;\r
+ mandatory true;\r
+ }\r
+\r
+ list physical-link {\r
+ description\r
+ "A list of physical links which compose the physical path.";\r
+\r
+ key "link-id";\r
+ leaf link-id {\r
+ description\r
+ "A unique ID for the physical link.";\r
+ type nemo-engine-common:physical-link-id;\r
+ }\r
+\r
+ leaf order {\r
+ description\r
+ "Specify the order of the physical link instance\r
+ in a sequence list.";\r
+ type uint32;\r
+ }\r
+ }\r
+\r
+ leaf metric {\r
+ description\r
+ "The routing metric of a physical path.";\r
+ type uint32;\r
+ }\r
+\r
+ leaf bandwidth {\r
+ description\r
+ "The bandwidth capacity of a physical path.\r
+ The unit is kbps.";\r
+ type uint32;\r
+ units kbps;\r
+ }\r
+\r
+ leaf delay {\r
+ description\r
+ "The packet transfer delay of a physical path.\r
+ The unit is millisecond.";\r
+ type uint32;\r
+ units millisecond;\r
+ }\r
+ }\r
+\r
+ container physical-network {\r
+ description\r
+ "Contains all physical nodes, links and tunnels\r
+ in the underlying network.";\r
+\r
+ container physical-nodes {\r
+ list physical-node {\r
+ description\r
+ "The list of all physical nodes in the underlying network.";\r
+\r
+ key "node-id";\r
+ uses physical-node-instance;\r
+ }\r
+ }\r
+\r
+ container physical-links {\r
+ list physical-link {\r
+ description\r
+ "The list of all physical links in the underlying network.";\r
+\r
+ key "link-id";\r
+ uses physical-link-instance;\r
+ }\r
+ }\r
+\r
+ container physical-hosts {\r
+ list physical-host {\r
+ description\r
+ "The list of all physical hosts in the underlying network.";\r
+\r
+ key "host-id";\r
+ uses physical-host-instance;\r
+ }\r
+ }\r
+\r
+ container physical-paths {\r
+ list physical-path {\r
+ description\r
+ "The list of all physical tunnels in the underlying network.";\r
+\r
+ key "path-id";\r
+ uses physical-path-instance;\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module generic-virtual-network {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:generic:virtual:network";\r
+ prefix "generic-vn";\r
+\r
+ import nemo-engine-common {prefix nemo-engine-common;}\r
+ import generic-physical-network {prefix generic-pn;}\r
+ import nemo-common {prefix nemo-common;}\r
+ import ietf-inet-types {\r
+ prefix inet;\r
+ revision-date 2010-09-24;\r
+ }\r
+ import ietf-yang-types {\r
+ prefix yang;\r
+ revision-date 2010-09-24;\r
+ }\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ grouping virtual-port-instance {\r
+ description\r
+ "Represents a virtual port instance and it's metadata.";\r
+\r
+ leaf port-id {\r
+ description\r
+ "A unique ID for a virtual port.";\r
+ type nemo-engine-common:virtual-port-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf port-type {\r
+ description\r
+ "The type of a virtual port.";\r
+ type enumeration {\r
+ enum external {\r
+ description\r
+ "The virtual port is connected to a external host\r
+ or network device.";\r
+ }\r
+ enum internal {\r
+ description\r
+ "The virtual port is connected to a virtual node.";\r
+ }\r
+ }\r
+ mandatory true;\r
+ }\r
+\r
+ leaf bandwidth {\r
+ description\r
+ "The bandwidth capacity of a virtual port.\r
+ The unit is kbps.";\r
+ type uint32;\r
+ units kbps;\r
+ }\r
+\r
+ container external-mac-addresses {\r
+ description\r
+ "A list of external mac addresses in the layer2 network\r
+ that connects to the virtual port.";\r
+\r
+ leaf-list external-mac-address {\r
+ type yang:mac-address;\r
+ }\r
+ }\r
+\r
+ container external-ip-prefixes {\r
+ description\r
+ "A list of external ip prefixes in the layer3 network\r
+ that connects to the virtual port.";\r
+\r
+ leaf-list external-ip-prefix {\r
+ type inet:ip-prefix;\r
+ }\r
+ }\r
+\r
+ list physical-resource-requirement {\r
+ description\r
+ "A list of physical port attribute requirements\r
+ for selecting physical port resource.";\r
+\r
+ key "attribute-name";\r
+ uses generic-pn:attribute-instance;\r
+\r
+ leaf attribute-match-pattern {\r
+ description\r
+ "The match pattern for an attribute instance.\r
+ It represents the arithmetic logic.";\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping virtual-node-instance {\r
+ description\r
+ "Represents a virtual node instance and it's metadata.";\r
+\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for a virtual node.";\r
+ type nemo-engine-common:virtual-node-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf node-type {\r
+ description\r
+ "The type of a virtual node.";\r
+ type enumeration {\r
+ enum vswitch;\r
+ enum vrouter;\r
+ enum vfirewall;\r
+ enum vloadbalancer;\r
+ }\r
+ }\r
+\r
+ list virtual-port {\r
+ description\r
+ "A list of ports of a virtual node.";\r
+\r
+ key "port-id";\r
+ uses virtual-port-instance;\r
+ }\r
+\r
+ list physical-resource-requirement {\r
+ description\r
+ "A list of physical node attribute requirements\r
+ for selecting physical node resource.";\r
+\r
+ key "attribute-name";\r
+ uses generic-pn:attribute-instance;\r
+\r
+ leaf attribute-match-pattern {\r
+ description\r
+ "The match pattern for an attribute instance.\r
+ It represents the arithmetic logic.";\r
+ type enumeration {\r
+ enum less-than;\r
+ enum not-less-than;\r
+ enum equal;\r
+ enum not-equal;\r
+ enum greater-than;\r
+ enum not-greater-than;\r
+ enum between;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping virtual-link-instance {\r
+ description\r
+ "Represents a virtual link instance and it's metadata.";\r
+\r
+ leaf link-id {\r
+ description\r
+ "A unique ID for a virtual link.";\r
+ type nemo-engine-common:virtual-link-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf src-node-id {\r
+ description\r
+ "A unique ID for the source virtual node.";\r
+ type nemo-engine-common:virtual-node-id;\r
+ }\r
+\r
+ leaf src-port-id {\r
+ description\r
+ "A unique ID for the source virtual port.";\r
+ type nemo-engine-common:virtual-port-id;\r
+ }\r
+\r
+ leaf dest-node-id {\r
+ description\r
+ "A unique ID for the destination virtual node.";\r
+ type nemo-engine-common:virtual-node-id;\r
+ }\r
+\r
+ leaf dest-port-id {\r
+ description\r
+ "A unique ID for the destination virtual port.";\r
+ type nemo-engine-common:virtual-port-id;\r
+ }\r
+\r
+ leaf metric {\r
+ description\r
+ "The routing metric is used by routing computation.";\r
+ type uint32;\r
+ }\r
+\r
+ leaf bandwidth {\r
+ description\r
+ "The bandwidth capacity of a virtual link.\r
+ The unit is kbps.";\r
+ type uint32;\r
+ units kbps;\r
+ }\r
+\r
+ leaf delay {\r
+ description\r
+ "The packet transfer delay of a virtual link.\r
+ The unit is millisecond.";\r
+ type uint32;\r
+ units millisecond;\r
+ }\r
+\r
+ leaf delay-requirement {\r
+ description\r
+ "The packet transfer delay requirement which\r
+ is specified by the user and used in the virtual\r
+ network mapping.";\r
+ type uint32;\r
+ units millisecond;\r
+ }\r
+ }\r
+\r
+ grouping virtual-path-instance {\r
+ description\r
+ "Represents a virtual path instance and it's metadata.";\r
+\r
+ leaf path-id {\r
+ description\r
+ "A unique ID for a virtual path.";\r
+ type nemo-engine-common:virtual-path-id;\r
+ mandatory true;\r
+ }\r
+\r
+ list virtual-link {\r
+ description\r
+ "A list of virtual links which compose the virtual path.";\r
+\r
+ key "link-id";\r
+ leaf link-id {\r
+ description\r
+ "A unique ID for the virtual link.";\r
+ type nemo-engine-common:virtual-link-id;\r
+ }\r
+\r
+ leaf order {\r
+ description\r
+ "Specify the order of the virtual link instance\r
+ in a sequence list.";\r
+ type uint32;\r
+ }\r
+ }\r
+\r
+ leaf metric {\r
+ description\r
+ "The routing metric of a virtual path.";\r
+ type uint32;\r
+ }\r
+\r
+ leaf bandwidth {\r
+ description\r
+ "The bandwidth capacity of a virtual path.\r
+ The unit is kbps.";\r
+ type uint32;\r
+ units kbps;\r
+ }\r
+\r
+ leaf delay {\r
+ description\r
+ "The packet transfer delay of a virtual path.\r
+ The unit is millisecond.";\r
+ type uint32;\r
+ units millisecond;\r
+ }\r
+ }\r
+\r
+ grouping virtual-route-instance {\r
+ description\r
+ "Represents a route instance in the virtual network.";\r
+\r
+ leaf src-node-id {\r
+ description\r
+ "A unique ID for the source virtual node.";\r
+ type nemo-engine-common:virtual-node-id;\r
+ }\r
+\r
+ leaf dest-node-id {\r
+ description\r
+ "A unique ID for the destination virtual node.";\r
+ type nemo-engine-common:virtual-node-id;\r
+ }\r
+\r
+ leaf path-id {\r
+ description\r
+ "A unique ID for the virtual path.";\r
+ type nemo-engine-common:virtual-path-id;\r
+ }\r
+ }\r
+\r
+ grouping virtual-arp-instance {\r
+ description\r
+ "Represents a arp instance in the virtual network.";\r
+\r
+ leaf ip-address {\r
+ description\r
+ "Represents the ip address for an ARP entry.";\r
+ type inet:ip-address;\r
+ }\r
+\r
+ leaf mac-address {\r
+ description\r
+ "Represents the mac address for an ARP entry.";\r
+ type yang:mac-address;\r
+ }\r
+\r
+ leaf node-id {\r
+ description\r
+ "A unique ID for the virtual node that connects to\r
+ the host corresponding to the ARP entry.";\r
+ type nemo-engine-common:virtual-node-id;\r
+ }\r
+\r
+ leaf port-id {\r
+ description\r
+ "A unique ID for the virtual port that connects to\r
+ the host corresponding to the ARP entry.";\r
+ type nemo-engine-common:virtual-port-id;\r
+ }\r
+ }\r
+\r
+ container virtual-networks {\r
+ description\r
+ "Contains all virtual networks that the NEMO engine maintains.";\r
+\r
+ list virtual-network {\r
+ description\r
+ "A virtual network which a user created.";\r
+\r
+ key "network-id";\r
+ leaf network-id {\r
+ description\r
+ "A unique ID for a virtual network.";\r
+ type nemo-engine-common:virtual-network-id;\r
+ }\r
+\r
+ leaf user-id {\r
+ description\r
+ "The user ID for the virtual network.";\r
+ type nemo-common:user-id;\r
+ }\r
+\r
+ container virtual-nodes {\r
+ list virtual-node {\r
+ description\r
+ "All virtual nodes in the virtual network.";\r
+\r
+ key "node-id";\r
+ uses virtual-node-instance;\r
+ }\r
+ }\r
+\r
+ container virtual-links {\r
+ list virtual-link {\r
+ description\r
+ "All virtual links in the virtual network.";\r
+\r
+ key "link-id";\r
+ uses virtual-link-instance;\r
+ }\r
+ }\r
+\r
+ container virtual-paths {\r
+ list virtual-path {\r
+ description\r
+ "All virtual paths in the virtual network.";\r
+\r
+ key "path-id";\r
+ uses virtual-path-instance;\r
+ }\r
+ }\r
+\r
+ container virtual-routes {\r
+ list virtual-route {\r
+ description\r
+ "All virtual routes in the virtual network.";\r
+\r
+ key "src-node-id dest-node-id";\r
+ uses virtual-route-instance;\r
+ }\r
+ }\r
+\r
+ container virtual-arps {\r
+ list virtual-arp {\r
+ description\r
+ "All virtual ARP entries in the virtual network.";\r
+\r
+ key "ip-address";\r
+ uses virtual-arp-instance;\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module intent-mapping-result {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:intent:mapping:result";\r
+ prefix "intent-mapping-result";\r
+\r
+ import nemo-engine-common {prefix nemo-engine-common;}\r
+ import nemo-common {prefix nemo-common;}\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ grouping virtual-resource-instance {\r
+ description\r
+ "Represents the abstract entity of the virtual resource,\r
+ which can be a vport, vnode, vlink or vpath.";\r
+\r
+ leaf virtual-resource-id {\r
+ description\r
+ "A unique ID for a virtual resource.";\r
+ type nemo-engine-common:virtual-resource-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf virtual-resource-type {\r
+ description\r
+ "The type of the virtual resource.";\r
+ type enumeration {\r
+ enum vport;\r
+ enum vnode;\r
+ enum vlink;\r
+ enum vpath;\r
+ }\r
+ }\r
+\r
+ leaf virtual-resource-entity-id {\r
+ description\r
+ "A unique ID for the entity corresponding to\r
+ the virtual resource.";\r
+ type nemo-engine-common:virtual-resource-entity-id;\r
+ }\r
+\r
+ leaf parent-virtual-resource-entity-id {\r
+ description\r
+ "A unique ID for the parent entity corresponding\r
+ to the virtual resource. If the resource entity\r
+ is a virtual port, it's parent entity is the\r
+ virtual node which it belongs to.";\r
+ type nemo-engine-common:virtual-resource-entity-id;\r
+ }\r
+ }\r
+\r
+ grouping physical-resource-instance {\r
+ description\r
+ "Represents the abstract entity of the physical resource,\r
+ which can be a port, node or path.";\r
+\r
+ leaf physical-resource-id {\r
+ description\r
+ "A unique ID for a physical resource.";\r
+ type nemo-engine-common:physical-resource-id;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf physical-resource-type {\r
+ description\r
+ "The type of the physical resource.";\r
+ type enumeration {\r
+ enum port;\r
+ enum node;\r
+ enum path;\r
+ }\r
+ }\r
+\r
+ leaf physical-resource-entity-id {\r
+ description\r
+ "A unique ID for the entity corresponding to\r
+ the physical resource.";\r
+ type nemo-engine-common:physical-resource-entity-id;\r
+ }\r
+\r
+ leaf parent-physical-resource-entity-id {\r
+ description\r
+ "A unique ID for the parent entity corresponding\r
+ to the physical resource. If the resource entity\r
+ is a physical port, it's parent entity is the\r
+ physical node which it belongs to.";\r
+ type nemo-engine-common:physical-resource-entity-id;\r
+ }\r
+ }\r
+\r
+ container intent-vn-mapping-results {\r
+ description\r
+ "Contains the intent-vn mapping results of all users.";\r
+\r
+ list user-intent-vn-mapping {\r
+ description\r
+ "Represents the intent-vn mapping results of a user.";\r
+\r
+ key "user-id";\r
+ leaf user-id {\r
+ description\r
+ "The user id for the intents that are mapped to\r
+ the virtual resource.";\r
+ type nemo-common:user-id;\r
+ }\r
+\r
+ leaf virtual-network-id {\r
+ description\r
+ "The virtual network id of the user.";\r
+ type nemo-engine-common:virtual-network-id;\r
+ }\r
+\r
+ list intent-vn-mapping-result {\r
+ description\r
+ "Represents a intent-vn mapping result of the user.";\r
+\r
+ key "intent-id";\r
+ leaf intent-id {\r
+ description\r
+ "A unique ID for the user intent.";\r
+ type nemo-common:intent-id;\r
+ }\r
+\r
+ leaf intent-type {\r
+ description\r
+ "The type of the user intent.";\r
+ type enumeration {\r
+ enum node;\r
+ enum connection;\r
+ enum operation;\r
+ }\r
+ }\r
+\r
+ list virtual-resource {\r
+ description\r
+ "The list of virtual resource corresponding to\r
+ the user intent.";\r
+\r
+ key "virtual-resource-id";\r
+ uses virtual-resource-instance;\r
+\r
+ leaf order {\r
+ description\r
+ "Specify the order of the virtual resource instance\r
+ in a sequence list.";\r
+ type uint32;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ container vn-pn-mapping-results {\r
+ description\r
+ "Contains the vn-pn mapping results of all users.";\r
+\r
+ list user-vn-pn-mapping {\r
+ description\r
+ "Represents the vn-pn mapping results of a user.";\r
+\r
+ key "virtual-network-id";\r
+ leaf virtual-network-id {\r
+ description\r
+ "The virtual network id of the user.";\r
+ type nemo-engine-common:virtual-network-id;\r
+ }\r
+\r
+ leaf user-id {\r
+ description\r
+ "The user id for the virtual network.";\r
+ type nemo-common:user-id;\r
+ }\r
+\r
+ list vn-pn-mapping-result {\r
+ description\r
+ "Represents a vn-pn mapping result of the user.";\r
+\r
+ key "virtual-resource-entity-id";\r
+ uses virtual-resource-instance;\r
+\r
+ uses physical-resource-instance;\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module intent-processing-status {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:intent:processing:status";\r
+ prefix "intent-processing-status";\r
+\r
+ import nemo-common {prefix nemo-common;}\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ grouping intent-status {\r
+ leaf status {\r
+ description\r
+ "Represents the current processing status of the user intent\r
+ maintained by the NEMO engine or the user's transaction.";\r
+ type enumeration {\r
+ enum processing-succeeded {\r
+ description\r
+ "The user intent has been successfully processed by the\r
+ NEMO engine and the underlying network has been configured\r
+ by some renderer if necessary, or the user's transaction\r
+ has been processed successfully.";\r
+ }\r
+ enum in-processing {\r
+ description\r
+ "The user intent is being processed by the NEMO engine, or\r
+ some intents in the user's transaction are being processed.";\r
+ }\r
+ enum processing-failed {\r
+ description\r
+ "The processing for the user intent by the NEMO engine is\r
+ failed, the reason might be syntax error, insufficient\r
+ underlying network resources, etc, and is described in\r
+ the message in detail. Or the processing for the user's\r
+ transaction is failed.";\r
+ }\r
+ }\r
+ config false;\r
+ mandatory true;\r
+ }\r
+\r
+ leaf message {\r
+ description\r
+ "The human-readable and detailed message about the status.";\r
+ type string;\r
+ config false;\r
+ }\r
+ }\r
+\r
+ container intent-processing-statuses {\r
+ description\r
+ "Contains the intent processing statuses of all users\r
+ maintained by the NEMO engine.";\r
+\r
+ list user-intent-status {\r
+ description\r
+ "Represents the list of all users with their intent statuses.";\r
+\r
+ key "user-id";\r
+ leaf user-id {\r
+ description\r
+ "The unique ID for the user.";\r
+ type nemo-common:user-id;\r
+ }\r
+\r
+ container transaction-status {\r
+ description\r
+ "Contains the user's transaction status information.\r
+ When all user intents in the transaction have been\r
+ successfully processed, the transaction status will\r
+ be set to processing-succeeded. If the processing for\r
+ some user intents in the transaction is failed, the\r
+ transaction status will be set to processing-failed.";\r
+\r
+ uses intent-status;\r
+ }\r
+\r
+ container object-statuses {\r
+ description\r
+ "Contains all object intent statuses of the user.";\r
+\r
+ list node-status {\r
+ description\r
+ "The list of all node intent statuses of the user.";\r
+\r
+ key "node-id";\r
+ leaf node-id {\r
+ description\r
+ "The unique ID for the node.";\r
+ type nemo-common:node-id;\r
+ }\r
+\r
+ uses intent-status;\r
+ config false;\r
+ }\r
+\r
+ list connection-status {\r
+ description\r
+ "The list of all connection intent statuses of the user.";\r
+\r
+ key "connection-id";\r
+ leaf connection-id {\r
+ description\r
+ "The unique ID for the connection.";\r
+ type nemo-common:connection-id;\r
+ }\r
+\r
+ uses intent-status;\r
+ config false;\r
+ }\r
+\r
+ list flow-status {\r
+ description\r
+ "The list of all flow intent statuses of the user.";\r
+\r
+ key "flow-id";\r
+ leaf flow-id {\r
+ description\r
+ "The unique ID for the flow.";\r
+ type nemo-common:flow-id;\r
+ }\r
+\r
+ uses intent-status;\r
+ config false;\r
+ }\r
+ }\r
+\r
+ container operation-statuses {\r
+ description\r
+ "Contains all operation intent statuses of the user.";\r
+\r
+ list operation-status {\r
+ description\r
+ "The list of all operation intent statuses of the user.";\r
+\r
+ key "operation-id";\r
+ leaf operation-id {\r
+ description\r
+ "The unique ID for the operation.";\r
+ type nemo-common:operation-id;\r
+ }\r
+\r
+ uses intent-status;\r
+ config false;\r
+ }\r
+ }\r
+\r
+ container result-statuses {\r
+ // TBD\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module nemo-engine-common {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:engine:common";\r
+ prefix "nemo-engine-common";\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ // *********************\r
+ // * Base Types\r
+ // *********************\r
+ typedef name {\r
+ description\r
+ "A generic string name type. Must start with a letter";\r
+ type string {\r
+ pattern '[a-zA-Z]([a-zA-Z0-9\-_.])*';\r
+ length "1..256";\r
+ }\r
+ }\r
+\r
+ // UUID type from ietf-yang-types@2013-07-15\r
+ typedef uuid {\r
+ type string {\r
+ pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'\r
+ + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';\r
+ }\r
+ description\r
+ "A Universally Unique IDentifier in the string representation\r
+ defined in RFC 4122. The canonical representation uses\r
+ lower case characters.\r
+\r
+ The following is an example of a UUID in string\r
+ representation: f81d4fae-7dec-11d0-a765-00a0c91e6bf6";\r
+ reference\r
+ "RFC 4122: A Universally Unique IDentifier (UUID) URN\r
+ Namespace";\r
+ }\r
+\r
+ typedef unique-id {\r
+ description\r
+ "A globally unique identifier.";\r
+ type uuid;\r
+ }\r
+\r
+ // *********************\r
+ // * Unique IDs\r
+ // *********************\r
+ typedef physical-port-id {\r
+ description\r
+ "A unique ID for a physical port.";\r
+ type string;\r
+ }\r
+\r
+ typedef physical-node-id {\r
+ description\r
+ "A unique ID for a physical node.";\r
+ type string;\r
+ }\r
+\r
+ typedef physical-link-id {\r
+ description\r
+ "A unique ID for a physical link.";\r
+ type string;\r
+ }\r
+\r
+ typedef physical-host-id {\r
+ description\r
+ "A unique ID for a physical host.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef physical-path-id {\r
+ description\r
+ "A unique ID for a physical path.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-port-id {\r
+ description\r
+ "A unique ID for a virtual port.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-node-id {\r
+ description\r
+ "A unique ID for a virtual node.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-link-id {\r
+ description\r
+ "A unique ID for a virtual link.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-path-id {\r
+ description\r
+ "A unique ID for a virtual path.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-network-id {\r
+ description\r
+ "A unique ID for a virtual network.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-resource-id {\r
+ description\r
+ "A unique ID for the virtual resource.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef virtual-resource-entity-id {\r
+ description\r
+ "A unique ID for a virtual resource entity.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef physical-resource-id {\r
+ description\r
+ "A unique ID for the physical resource.";\r
+ type unique-id;\r
+ }\r
+\r
+ typedef physical-resource-entity-id {\r
+ description\r
+ "A unique ID for a physical resource entity.";\r
+ type string;\r
+ }\r
+\r
+ // *********************\r
+ // * Names\r
+ // *********************\r
+ typedef attribute-name {\r
+ description\r
+ "A name for a physical port or node attribute.";\r
+ type name;\r
+ }\r
+\r
+ typedef physical-host-name {\r
+ description\r
+ "A name for a physical host.";\r
+ type name;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+module nemo-engine-impl {\r
+ yang-version 1;\r
+\r
+ namespace "urn:opendaylight:params:xml:ns:yang:nemo:engine:impl";\r
+ prefix "nemo-engine-impl";\r
+\r
+ import config { prefix config; revision-date 2013-04-05; }\r
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }\r
+\r
+ description\r
+ "This module contains the base YANG definitions for\r
+ NEMO engine implementation.";\r
+\r
+ revision "2015-10-10" {\r
+ description\r
+ "Initial revision.";\r
+ }\r
+\r
+ identity nemo-engine-impl {\r
+ base config:module-type;\r
+ config:java-name-prefix NemoEngine;\r
+ }\r
+\r
+ augment "/config:modules/config:module/config:configuration" {\r
+ case nemo-engine-impl {\r
+ when "/config:modules/config:module/config:type = 'nemo-engine-impl'";\r
+\r
+ container data-broker {\r
+ uses config:service-ref {\r
+ refine type {\r
+ mandatory false;\r
+ config:required-identity mdsal:binding-async-data-broker;\r
+ }\r
+ }\r
+ }\r
+ container rpc-registry {\r
+ uses config:service-ref {\r
+ refine type {\r
+ mandatory true;\r
+ config:required-identity mdsal:binding-rpc-registry;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+#!/usr/bin/python
+#Filename:servicechain.py
+import requests,json
+import argparse, sys
+from requests.auth import HTTPBasicAuth
+
+USERNAME='admin'
+PASSWORD='admin'
+
+TRANSACTION_BEGIN="http://%s:8181/restconf/operations/nemo-intent:begin-transaction"
+TRANSACTION_END="http://%s:8181/restconf/operations/nemo-intent:end-transaction"
+REGISTER_USER="http://%s:8181/restconf/operations/nemo-intent:register-user"
+STRUCTURE_UPDATE_USERS="http://%s:8181/restconf/operations/nemo-intent:structure-style-nemo-update"
+
+def register_user(contHost):
+ data={
+ "input":{
+ "user-id":"14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "user-name":"user2",
+ "user-password":"abc",
+ "user-role":"tenant"
+ }
+ }
+ post(REGISTER_USER % contHost, data)
+
+def transaction_begin(contHost):
+ data={
+ "input":{
+ "user-id":"14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "user-name":"user2",
+ "user-password":"abc",
+ "user-role":"tenant"
+ }
+ }
+ post(TRANSACTION_BEGIN % contHost, data)
+
+def transaction_end(contHost):
+ data={
+ "input":{
+ "user-id":"14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "user-name":"user2",
+ "user-password":"abc",
+ "user-role":"tenant"
+ }
+ }
+ post(TRANSACTION_END % contHost, data)
+
+def add_server1_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "server1",
+ "node-type": "host",
+ "node-id":"7b796915-adf4-4356-b5ca-de005ac410c1"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_server2_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "server2",
+ "node-type": "host",
+ "node-id":"22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_vm1_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "vm1",
+ "node-type": "host",
+ "node-id":"1eaf9a67-a171-42a8-9282-71cf702f61dd"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_vm2_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "vm2",
+ "node-type": "host",
+ "node-id":"6c787caa-156a-49ed-8546-547bdccf283c"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_enterpise_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "enterprise",
+ "node-type": "ext-group",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:4:2"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "static"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.13.0/24"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_internet_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "internet",
+ "node-type": "ext-group",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3:4"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "static"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ #wait for external network ip
+ "value": "172.168.1.0/24"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "d463232f-363f-491c-a6f5-097ed0a794d3"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_dmz_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "dmz",
+ "node-type": "l2-group",
+ "sub-node": [
+ {
+ "node-id":"7b796915-adf4-4356-b5ca-de005ac410c1",
+ "order":"0"
+ }
+ ],
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.11.0/24"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "gateway-ip",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.11.1"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_interior_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "interior",
+ "node-type": "l2-group",
+ "sub-node": [
+ {
+ "node-id":"22282cca-9a13-4d0c-a67e-a933ebb0b0ae",
+ "order":"0"
+ },
+ {
+ "node-id":"1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "order":"0"
+ },
+ {
+ "node-id":"6c787caa-156a-49ed-8546-547bdccf283c",
+ "order":"0"
+ }
+ ],
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.12.0/24"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "gateway-ip",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.12.1"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_enterprise_interior_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c1",
+ "connection-id": "30da6667-608e-4d2f-bb50-79e5cabcc523",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ },
+ {
+ "order": "0",
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ }
+ ],
+ "connection-type": "p2p",
+ "property": [
+ {
+ "property-name": "bandwidth",
+ "property-values": {
+ "int-value": [
+ {
+ "order": "0",
+ "value": "128"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_interior_dmz_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c2",
+ "connection-id": "b49e3960-c08d-4fff-b9fc-08b65ebcde2c",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ },
+ {
+ "order": "0",
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_dmz_internet_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c3",
+ "connection-id": "e0d56fee-7235-4748-a2a1-eb5e3733d866",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ },
+ {
+ "order": "0",
+ "node-id": "d463232f-363f-491c-a6f5-097ed0a794d3"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def update_enterprise_interior_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c1",
+ "connection-id": "30da6667-608e-4d2f-bb50-79e5cabcc523",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ },
+ {
+ "order": "0",
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ }
+ ],
+ "connection-type": "p2p",
+ "property": [
+ {
+ "property-name": "bandwidth",
+ "property-values": {
+ "int-value": [
+ {
+ "order": "0",
+ "value": "512"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def post(url, data):
+ headers = {'Content-type': 'application/yang.data+json',
+ 'Accept': 'application/yang.data+json'}
+ print "POST %s" % url
+ print json.dumps(data, indent=4, sort_keys=True)
+ r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ print r.text
+ r.raise_for_status()
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--controller', default='127.0.0.1', help='controller IP')
+ args=parser.parse_args()
+
+ # CREATE User;
+ register_user(args.controller)
+
+ # IMPORT Node server1 Type host;
+ transaction_begin(args.controller)
+ add_server1_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node server2 Type host;
+ #transaction_begin(args.controller)
+ add_server2_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node vm1 Type host;
+ #transaction_begin(args.controller)
+ add_vm1_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node vm2 Type host;
+ #transaction_begin(args.controller)
+ add_vm2_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node enterprise Type ext-group Property location:openflow:4:2, ip-prefix:192.18.13.0/24;
+ #transaction_begin(args.controller)
+ add_enterpise_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Node interior Type l2-group Contain server1,vm1,vm2;
+ #transaction_begin(args.controller)
+ add_interior_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Node dmz Type l2-group Contain server2;
+ #transaction_begin(args.controller)
+ add_dmz_node(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node internet Type ext-group Property location:openflow:3:4, ip-prefix:172.168.1.0/24;
+ #transaction_begin(args.controller)
+ add_internet_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c1 Endnodes enterprise,interior Property bandwidth:128(kbps);
+ #transaction_begin(args.controller)
+ add_enterprise_interior_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c2 Endnodes interior,dmz;
+ #transaction_begin(args.controller)
+ add_interior_dmz_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c3 Endnodes dmz,internet;
+ #transaction_begin(args.controller)
+ add_dmz_internet_connection(args.controller)
+ transaction_end(args.controller)
+
+ # UPDATE Connection c1 Endnodes enterprise,interior Property bandwidth:512(kbps);
+ #transaction_begin(args.controller)
+ #update_enterprise_interior_connection(args.controller)
+ #transaction_end(args.controller)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python
+#Filename:servicechain.py
+import requests,json
+import argparse, sys
+from requests.auth import HTTPBasicAuth
+
+USERNAME='admin'
+PASSWORD='admin'
+
+TRANSACTION_BEGIN="http://%s:8181/restconf/operations/nemo-intent:begin-transaction"
+TRANSACTION_END="http://%s:8181/restconf/operations/nemo-intent:end-transaction"
+REGISTER_USER="http://%s:8181/restconf/operations/nemo-intent:register-user"
+STRUCTURE_UPDATE_USERS="http://%s:8181/restconf/operations/nemo-intent:structure-style-nemo-update"
+
+def register_user(contHost):
+ data={
+ "input":{
+ "user-id":"14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "user-name":"user2",
+ "user-password":"abc",
+ "user-role":"tenant"
+ }
+ }
+ post(REGISTER_USER % contHost, data)
+
+def transaction_begin(contHost):
+ data={
+ "input":{
+ "user-id":"14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "user-name":"user2",
+ "user-password":"abc",
+ "user-role":"tenant"
+ }
+ }
+ post(TRANSACTION_BEGIN % contHost, data)
+
+def transaction_end(contHost):
+ data={
+ "input":{
+ "user-id":"14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "user-name":"user2",
+ "user-password":"abc",
+ "user-role":"tenant"
+ }
+ }
+ post(TRANSACTION_END % contHost, data)
+
+def add_server1_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "server1",
+ "node-type": "host",
+ "node-id":"7b796915-adf4-4356-b5ca-de005ac410c1"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_server2_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "server2",
+ "node-type": "host",
+ "node-id":"22282cca-9a13-4d0c-a67e-a933ebb0b0ae"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_vm1_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "vm1",
+ "node-type": "host",
+ "node-id":"1eaf9a67-a171-42a8-9282-71cf702f61dd"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_vm2_host(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "vm2",
+ "node-type": "host",
+ "node-id":"6c787caa-156a-49ed-8546-547bdccf283c"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_enterpise_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "enterprise",
+ "node-type": "ext-group",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:4:2"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "static"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.13.0/24"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_internet_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "internet",
+ "node-type": "ext-group",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3:4"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "static"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ #wait for external network ip
+ "value": "172.168.1.0/24"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "d463232f-363f-491c-a6f5-097ed0a794d3"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_dmz_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "dmz",
+ "node-type": "l2-group",
+ "sub-node": [
+ {
+ "node-id":"7b796915-adf4-4356-b5ca-de005ac410c1",
+ "order":"0"
+ }
+ ],
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.11.0/24"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "gateway-ip",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.11.1"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_interior_node(contHost):
+ data={
+ "input":{
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "interior",
+ "node-type": "l2-group",
+ "sub-node": [
+ {
+ "node-id":"22282cca-9a13-4d0c-a67e-a933ebb0b0ae",
+ "order":"0"
+ },
+ {
+ "node-id":"1eaf9a67-a171-42a8-9282-71cf702f61dd",
+ "order":"0"
+ },
+ {
+ "node-id":"6c787caa-156a-49ed-8546-547bdccf283c",
+ "order":"0"
+ }
+ ],
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.12.0/24"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "gateway-ip",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.12.1"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_enterprise_interior_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c1",
+ "connection-id": "30da6667-608e-4d2f-bb50-79e5cabcc523",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ },
+ {
+ "order": "0",
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ }
+ ],
+ "connection-type": "p2p",
+ "property": [
+ {
+ "property-name": "bandwidth",
+ "property-values": {
+ "int-value": [
+ {
+ "order": "0",
+ "value": "128"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_interior_dmz_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c2",
+ "connection-id": "b49e3960-c08d-4fff-b9fc-08b65ebcde2c",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ },
+ {
+ "order": "0",
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_dmz_internet_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c3",
+ "connection-id": "e0d56fee-7235-4748-a2a1-eb5e3733d866",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ },
+ {
+ "order": "0",
+ "node-id": "d463232f-363f-491c-a6f5-097ed0a794d3"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def update_enterprise_interior_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user2",
+ "user-role": "tenant",
+ "user-password": "abc",
+ "user-id": "14ce424a-3e50-4a2a-ad5c-b29845158c8b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c1",
+ "connection-id": "30da6667-608e-4d2f-bb50-79e5cabcc523",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ },
+ {
+ "order": "0",
+ "node-id": "175425f7-c9c9-474a-962c-70cb6c180d4d"
+ }
+ ],
+ "connection-type": "p2p",
+ "property": [
+ {
+ "property-name": "bandwidth",
+ "property-values": {
+ "int-value": [
+ {
+ "order": "0",
+ "value": "1024"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def post(url, data):
+ headers = {'Content-type': 'application/yang.data+json',
+ 'Accept': 'application/yang.data+json'}
+ print "POST %s" % url
+ print json.dumps(data, indent=4, sort_keys=True)
+ r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ print r.text
+ r.raise_for_status()
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--controller', default='127.0.0.1', help='controller IP')
+ args=parser.parse_args()
+
+ # CREATE User;
+ #register_user(args.controller)
+
+ # IMPORT Node server1 Type host;
+ #transaction_begin(args.controller)
+ #add_server1_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node server2 Type host;
+ #transaction_begin(args.controller)
+ #add_server2_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node vm1 Type host;
+ #transaction_begin(args.controller)
+ #add_vm1_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node vm2 Type host;
+ #transaction_begin(args.controller)
+ #add_vm2_host(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node enterprise Type ext-group Property location:openflow:4:2, ip-prefix:192.18.13.0/24;
+ #transaction_begin(args.controller)
+ #add_enterpise_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Node interior Type l2-group Contain server1,vm1,vm2;
+ #transaction_begin(args.controller)
+ #add_interior_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Node dmz Type l2-group Contain server2;
+ #transaction_begin(args.controller)
+ #add_dmz_node(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node internet Type ext-group Property location:openflow:3:4, ip-prefix:172.168.1.0/24;
+ #transaction_begin(args.controller)
+ #add_internet_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c1 Endnodes enterprise,interior Property bandwidth:128(kbps);
+ #transaction_begin(args.controller)
+ #add_enterprise_interior_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c2 Endnodes interior,dmz;
+ #transaction_begin(args.controller)
+ #add_interior_dmz_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c3 Endnodes dmz,internet;
+ #transaction_begin(args.controller)
+ #add_dmz_internet_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # UPDATE Connection c1 Endnodes enterprise,interior Property bandwidth:1024(kbps);
+ transaction_begin(args.controller)
+ update_enterprise_interior_connection(args.controller)
+ transaction_end(args.controller)
\ No newline at end of file
--- /dev/null
+#!/usr/bin/python
+#Filename:servicechain.py
+import requests,json
+import argparse, sys
+from requests.auth import HTTPBasicAuth
+
+USERNAME='admin'
+PASSWORD='admin'
+
+TRANSACTION_BEGIN="http://%s:8181/restconf/operations/nemo-intent:begin-transaction/"
+TRANSACTION_END="http://%s:8181/restconf/operations/nemo-intent:end-transaction/"
+REGISTER_USER="http://%s:8181/restconf/operations/nemo-intent:register-user/"
+STRUCTURE_UPDATE_USERS="http://%s:8181/restconf/operations/nemo-intent:structure-style-nemo-update/"
+
+def register_user(contHost):
+ data={
+ "input":{
+ "user-id":"af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "user-name":"user1",
+ "user-password":"abcd",
+ "user-role":"tenant"
+ }
+ }
+ post(REGISTER_USER % contHost, data)
+
+def transaction_begin(contHost):
+ data={
+ "input":{
+ "user-id":"af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "user-name":"user1",
+ "user-password":"abcd",
+ "user-role":"tenant"
+ }
+ }
+ post(TRANSACTION_BEGIN % contHost, data)
+
+def transaction_end(contHost):
+ data={
+ "input":{
+ "user-id":"af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "user-name":"user1",
+ "user-password":"abcd",
+ "user-role":"tenant"
+ }
+ }
+ post(TRANSACTION_END % contHost, data)
+
+
+def add_headquarter_node(contHost):
+ data={
+ "input":{
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "headquarter",
+ "node-type": "ext-group",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:4:2"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "static"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.11.0/24"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_site_node(contHost):
+ data={
+ "input":{
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "branch",
+ "node-type": "ext-group",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:3:4"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-network",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ac-info-protocol",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "static"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "ip-prefix",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "192.168.12.0/24"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_firewall_node(contHost):
+ data={
+ "input":{
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "fw1",
+ "node-type": "fw",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:1:1"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "operating-mode",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "c2cd9de6-ab25-4d3f-bff2-c4d785a41995"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_cache_node(contHost):
+ data={
+ "input":{
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "node":[
+ {
+ "node-name": "cache2",
+ "node-type": "cache",
+ "property": [
+ {
+ "property-name": "location",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "openflow:2:2"
+ }
+ ]
+ }
+ },
+ {
+ "property-name": "operating-mode",
+ "property-values": {
+ "string-value": [
+ {
+ "order": "0",
+ "value": "layer3"
+ }
+ ]
+ }
+ }
+ ],
+ "node-id": "a5a96dc7-51dd-44a5-802b-7e67a309fb36"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_chain_node(contHost):
+ data={
+ "input":{
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "node":[
+ { "sub-node": [
+ {
+ "order": "0",
+ "node-id": "c2cd9de6-ab25-4d3f-bff2-c4d785a41995"
+ },
+ {
+ "order": "1",
+ "node-id": "a5a96dc7-51dd-44a5-802b-7e67a309fb36"
+ }
+ ],
+ "node-name": "chain1",
+ "node-type": "chain-group",
+ "node-id": "41ee9aad-5f61-469d-99a9-e691d2a1de05"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_head_site_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c1",
+ "connection-id": "7175bac3-b785-2278-90ed-613480e354e8",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ },
+ {
+ "order": "0",
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_head_chain_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c2",
+ "connection-id": "9397bac3-d9a7-449a-b20f-8356a2f3760a",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "94a6fb90-b425-4ffd-9515-c0684aa4c37f"
+ },
+ {
+ "order": "0",
+ "node-id": "41ee9aad-5f61-469d-99a9-e691d2a1de05"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_site_chain_connection(contHost):
+ data={
+ "input": {
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "connection": [
+ {
+ "connection-name": "c3",
+ "connection-id": "fed2b570-2e80-4914-a5af-040594b651b9",
+ "end-node": [
+ {
+ "order": "0",
+ "node-id": "41ee9aad-5f61-469d-99a9-e691d2a1de05"
+ },
+ {
+ "order": "0",
+ "node-id": "b46cfa7f-93a3-43f4-ac20-09307c75feca"
+ }
+ ],
+ "connection-type": "p2p"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_flow(contHost):
+ data={
+ "input": {
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "objects":{
+ "flow": [
+ {
+ "match-item": [
+ {
+ "match-item-value": {
+ "string-value": "192.168.12.0/24"
+ },
+ "match-item-name": "src-ip"
+ },
+ {
+ "match-item-value": {
+ "string-value": "192.168.11.0/24"
+ },
+ "match-item-name": "dst-ip"
+ },
+ ],
+ "flow-id": "cf48eeee-882e-435a-adf4-ea22ba88331f",
+ "flow-name": "f1"
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+def add_operation(contHost):
+ data={
+ "input": {
+ "user-name": "user1",
+ "user-role": "tenant",
+ "user-password": "abcd",
+ "user-id": "af4fc2be-e3f4-4388-a8ef-3aabae872f2b",
+ "operations":{
+ "operation": [
+ {
+ "operation-name": "o1",
+ "target-object": "cf48eeee-882e-435a-adf4-ea22ba88331f",
+ "priority":"0",
+ "operation-id": "619ee3bb-1e40-480f-b0fa-a331820a5518",
+ "action":[
+ {
+ "action-name":"go-through",
+ "parameter-values":{
+ "string-value": [
+ {"value": "41ee9aad-5f61-469d-99a9-e691d2a1de05",
+ "order":"0"}
+ ]
+ },
+ "order":"0"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ post(STRUCTURE_UPDATE_USERS % contHost, data)
+
+
+def post(url, data):
+ headers = {'Content-type': 'application/yang.data+json',
+ 'Accept': 'application/yang.data+json'}
+ print "POST %s" % url
+ print json.dumps(data, indent=4, sort_keys=True)
+ r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+ print r.text
+ r.raise_for_status()
+
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--controller', default='127.0.0.1', help='controller IP')
+ args=parser.parse_args()
+
+ # CREATE User;
+ register_user(args.controller)
+
+ # CREATE Node headquarter Type ext-group Property location:openflow:4:2, ip-prefix:192.168.11.0/24;
+ transaction_begin(args.controller)
+ add_headquarter_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Node headquarter Type ext-group Property location:openflow:3:4,ip-prefix:192.168.12.0/24;
+ #transaction_begin(args.controller)
+ add_site_node(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node fw1 Type fw Property location:openflow:1:1;
+ #transaction_begin(args.controller)
+ add_firewall_node(args.controller)
+ #transaction_end(args.controller)
+
+ # IMPORT Node Cache2 Type cache Property location:openflow:2:2;
+ #transaction_begin(args.controller)
+ add_cache_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Node chain1 Type chain-group Contain fw1,cache2;
+ #transaction_begin(args.controller)
+ add_chain_node(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c1 Type p2p Endnodes headquarter,site;
+ #transaction_begin(args.controller)
+ add_head_site_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c2 Type p2p Endnodes headquarter,chain1;
+ #transaction_begin(args.controller)
+ add_head_chain_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Connection c3 Type p2p Endnodes site,chain1;
+ #transaction_begin(args.controller)
+ add_site_chain_connection(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Flow f1 Match src-ip:192.168.12.0/24, dst-ip:192.168.11.0/24;
+ #transaction_begin(args.controller)
+ add_flow(args.controller)
+ #transaction_end(args.controller)
+
+ # CREATE Operation o1 Priority 0 Target f1 Action go-through: chain1;
+ #transaction_begin(args.controller)
+ add_operation(args.controller)
+ transaction_end(args.controller)
+
+
</prerequisites>
<properties>
- <feature.test.version>1.6.0-SNAPSHOT</feature.test.version>
<feature.mdsal.version>1.3.0-SNAPSHOT</feature.mdsal.version>
<feature.dlux.version>0.3.0-SNAPSHOT</feature.dlux.version>
- <feature.flow.version>1.3.0-SNAPSHOT</feature.flow.version>
- <feature.yangtools.version>0.8.0-SNAPSHOT</feature.yangtools.version>
- <feature.adsal.version>0.10.0-SNAPSHOT</feature.adsal.version>
</properties>
<dependencyManagement>
<type>xml</type>
<scope>runtime</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-adsal</artifactId>
- <classifier>features</classifier>
- <version>${feature.adsal.version}</version>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
<dependency>
<groupId>org.opendaylight.dlux</groupId>
<artifactId>features-dlux</artifactId>
<properties>
<jacoco.version>0.7.2.201409121644</jacoco.version>
+ <sonar.jacoco.reportPath>target/code-coverage/jacoco.exec</sonar.jacoco.reportPath>
+ <sonar.jacoco.itReportPath>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
+ <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+ <liblldp.version>0.10.0-SNAPSHOT</liblldp.version>
</properties>
<dependencies>
+ <!-- model dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>yang-ext</artifactId>
+ </dependency>
+ <!-- project specific dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>openflowplugin-extension-nicira</artifactId>
+ <version>${openflowplugin.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>liblldp</artifactId>
+ <version>${liblldp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-net</groupId>
+ <artifactId>commons-net</artifactId>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nemo-api</artifactId>
<artifactId>nemo-impl</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
</plugins>
</pluginManagement>
<plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>org.codehaus.jackson,
+ org.codehaus.jackson.*,
+ org.joda.time.*,
+ </Export-Package>
+ <Import-Package>*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
<phase>package</phase>
<configuration>
<artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/etc/nemo/resource.json</file>
+ <type>json</type>
+ <classifier>resource</classifier>
+ </artifact>
<artifact>
<file>${project.build.directory}/classes/etc/opendaylight/karaf/config.xml</file>
<type>xml</type>
</configuration>
<executions>
<execution>
- <id>pre-test</id>
+ <id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
+ <configuration>
+ <destFile>${sonar.jacoco.reportPath}</destFile>
+ </configuration>
</execution>
<execution>
- <id>post-test</id>
+ <id>post-unit-test</id>
<goals>
<goal>report</goal>
</goals>
- <phase>test</phase>
+ <configuration>
+ <dataFile>${sonar.jacoco.reportPath}</dataFile>
+ </configuration>
</execution>
</executions>
</plugin>
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.renderer.openflow;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.util.concurrent.FutureCallback;\r
+import com.google.common.util.concurrent.Futures;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.concurrent.Executors;\r
+import java.util.concurrent.ScheduledExecutorService;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.VirtualNetworks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.IntentVnMappingResults;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.VnPnMappingResults;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNetworkId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+public class FlowTableManager implements AutoCloseable {\r
+ private static final Logger LOG = LoggerFactory.getLogger(FlowTableManager.class);\r
+\r
+ private final DataBroker dataProvider;\r
+\r
+ private ListenerRegistration<DataChangeListener> userVnPnMappingChangeListenerReg;\r
+\r
+ private FlowUtils flowUtils = null;\r
+\r
+ public FlowTableManager(DataBroker dataProvider, ResourceManager resourceManager){\r
+\r
+ this.dataProvider = dataProvider;\r
+ LOG.info("Initialized FlowTableManager.");\r
+ flowUtils = new FlowUtils(dataProvider, resourceManager);\r
+ //register listener\r
+ registerUserVnPnMappingListener();\r
+ }\r
+\r
+ private void registerUserVnPnMappingListener() {\r
+\r
+ //build userVnPnMappingIid\r
+ InstanceIdentifier<UserVnPnMapping> userVnPnMappingIid = InstanceIdentifier\r
+ .builder(VnPnMappingResults.class)\r
+ .child(UserVnPnMapping.class)\r
+ .build();\r
+ //register\r
+ userVnPnMappingChangeListenerReg = dataProvider.registerDataChangeListener(\r
+ LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid,\r
+ new UserVnPnMappingChangeListener(), DataChangeScope.BASE);\r
+ }\r
+\r
+\r
+ private User getUser(UserId userId) {\r
+\r
+ ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
+ InstanceIdentifier<User> userIid = InstanceIdentifier.builder(Users.class)\r
+ .child(User.class, new UserKey(userId))\r
+ .build();\r
+ Optional<User> result = null;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, userIid).get();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ if (result.isPresent()){\r
+ LOG.info("getUser OK");\r
+ return (result.get());\r
+\r
+ }else{\r
+ LOG.info("getUser ERROR");\r
+ return null;\r
+ }\r
+ }\r
+\r
+\r
+ private VirtualNetwork getVirtualNetwork(UserId userId) {\r
+\r
+ VirtualNetworkId virtualNetworkId = new VirtualNetworkId(userId.getValue());\r
+ VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(virtualNetworkId);\r
+\r
+ ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
+ InstanceIdentifier<VirtualNetwork> virtualNetworkIid = InstanceIdentifier\r
+ .builder(VirtualNetworks.class)\r
+ .child(VirtualNetwork.class, virtualNetworkKey)\r
+ .build();\r
+ Optional<VirtualNetwork> result = null;\r
+\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid).get();\r
+\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ if (result.isPresent()) {\r
+ LOG.info("getVirtualNetwork OK");\r
+ return (result.get());\r
+\r
+ }else{\r
+ LOG.info("getVirtualNetwork ERROR");\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private UserIntentVnMapping getUserIntentVnMapping(UserId userId) {\r
+\r
+ ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
+ InstanceIdentifier<UserIntentVnMapping> userIntentVnMappingIid = InstanceIdentifier\r
+ .builder(IntentVnMappingResults.class)\r
+ .child(UserIntentVnMapping.class, new UserIntentVnMappingKey(userId))\r
+ .build();\r
+ Optional<UserIntentVnMapping> result = null;\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid).get();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ if (result.isPresent()) {\r
+ LOG.info("getUserIntentVnMapping OK");\r
+ return (result.get());\r
+\r
+ }else{\r
+ LOG.info("getUserIntentVnMapping ERROR");\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private PhysicalNetwork getPhysicalNetwork() {\r
+\r
+ ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
+ InstanceIdentifier<PhysicalNetwork> physicalNetworkIid = InstanceIdentifier\r
+ .builder(PhysicalNetwork.class)\r
+ .build();\r
+ Optional<PhysicalNetwork> result = null;\r
+ try {\r
+ result = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, physicalNetworkIid).get();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ if (result.isPresent()) {\r
+ LOG.info("getPhysicalNetwork OK");\r
+ return (result.get());\r
+\r
+ }else{\r
+ LOG.info("getPhysicalNetwork ERROR");\r
+ return null;\r
+ }\r
+ }\r
+\r
+\r
+ //A listener implementation\r
+ private class UserVnPnMappingChangeListener implements DataChangeListener {\r
+\r
+ @Override\r
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
+ if ( null == change ) {\r
+ return;\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
+ if ( null != createdData && !createdData.isEmpty() ) {\r
+ for ( DataObject dataObject : createdData.values() ) {\r
+ if ( dataObject instanceof UserVnPnMapping ) {\r
+ LOG.info("Ready to update flow table.");\r
+ UserVnPnMapping userVnPnMapping = (UserVnPnMapping)dataObject;\r
+ UserId userId = userVnPnMapping.getUserId();\r
+\r
+ User user = getUser(userId);\r
+ VirtualNetwork virtualNetwork = getVirtualNetwork(userId);\r
+ UserIntentVnMapping userIntentVnMapping = getUserIntentVnMapping(userId);\r
+ PhysicalNetwork physicalNetwork = getPhysicalNetwork();\r
+ if(physicalNetwork == null)\r
+ {\r
+ LOG.debug("Physical Network data are not present.");\r
+ return;\r
+ }\r
+ PhysicalNodes physicalNodes= physicalNetwork.getPhysicalNodes();\r
+ List<PhysicalNode> physicalNodeList = physicalNodes.getPhysicalNode();\r
+ flowUtils.init(physicalNodeList);\r
+\r
+ flowUtils.updateFlowTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ LOG.info("Already call flowUtils.updateFlowTable().");\r
+ }\r
+ }\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();\r
+ if ( null != updatedData && !updatedData.isEmpty() ) {\r
+ for ( DataObject dataObject : updatedData.values() ) {\r
+ if ( dataObject instanceof UserVnPnMapping ) {\r
+ UserVnPnMapping userVnPnMapping = (UserVnPnMapping)dataObject;\r
+ UserId userId = userVnPnMapping.getUserId();\r
+\r
+ flowUtils.deleteFlowEntries(userId);\r
+\r
+ User user = getUser(userId);\r
+ VirtualNetwork virtualNetwork = getVirtualNetwork(userId);\r
+ UserIntentVnMapping userIntentVnMapping = getUserIntentVnMapping(userId);\r
+ PhysicalNetwork physicalNetwork = getPhysicalNetwork();\r
+ if(physicalNetwork == null)\r
+ {\r
+ LOG.debug("Physical Network data are not present.");\r
+ return;\r
+ }\r
+\r
+ flowUtils.updateFlowTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ }\r
+ }\r
+ }\r
+\r
+ Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
+ Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
+ if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
+ DataObject dataObject;\r
+\r
+ for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
+ dataObject = originalData.get(instanceId);\r
+ if ( null != dataObject && dataObject instanceof UserVnPnMapping ) {\r
+ UserVnPnMapping userVnPnMapping = (UserVnPnMapping)dataObject;\r
+ flowUtils.deleteFlowEntries(userVnPnMapping.getUserId());\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+\r
+ if ( null != userVnPnMappingChangeListenerReg ) {\r
+ userVnPnMappingChangeListenerReg.close();\r
+ }\r
+ if ( null != flowUtils ) {\r
+ flowUtils.close();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.renderer.openflow;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.mpls.ttl._case.DecMplsTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.mpls.ttl._case.DecMplsTtlBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsAction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.BandId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFlags;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DropBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeader;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.meter.band.header.MeterBandTypesBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalLinks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalPaths;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPathBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArp;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArpKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResource;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMapping;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.user.vn.pn.mapping.VnPnMappingResult;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.IntentId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.MatchItemName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.*;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.flow.instance.MatchItem;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.math.BigInteger;\r
+import java.util.*;\r
+\r
+public class FlowUtils implements AutoCloseable {\r
+ private static final Logger LOG = LoggerFactory.getLogger(FlowUtils.class);\r
+\r
+ private static final short IN_PORT_TABLE_ID = 0;\r
+ private static final short MPLS_LABEL_TABLE_ID = 1;\r
+ private static final short MAC_TABLE_ID = 2;\r
+ private static final short IP_TABLE_ID = 3;\r
+ private static final short ARP_TABLE_ID = 4;\r
+\r
+ private static final int DEFAULT_FLOW_PRIORITY = 0;\r
+ private static final String DEFAULT_METADATA_MASK = "ffffffffffffffff";\r
+\r
+ private static final int ETH_TYPE_IP = 0x0800;\r
+ private static final int ETH_TYPE_MPLS = 0x8847;\r
+ private static final int ETH_TYPE_ARP = 0x0806;\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ private Map<PhysicalNodeId, MplsLabelGenerator> mplsGenerators;\r
+ private Map<PhysicalNodeId, MeterIdGenerator> meterIdGenerators;\r
+ private Map<PhysicalPathId, List<Integer>> mplsLabelsOfPhysicalPaths;\r
+ private Map<PhysicalPathId, Long> meterIdsOfPhysicalPaths;\r
+ private Map<UserId, Long> metadatas;\r
+ private long currentMetadata = 0;\r
+\r
+ private PhysicalNetworkHelper physicalNetworkHelper;\r
+ private VirtualNetworkHelper virtualNetworkHelper;\r
+\r
+ //liushixing\r
+ private Map<UserId, List<InstanceIdentifier<Flow>>> flowIdsOfUsers;\r
+ private Map<UserId, List<InstanceIdentifier<Meter>>> meterIdIdsOfUsers;\r
+// private List<PhysicalPortId> assignedPortForInPort;\r
+ private ResourceManager resourceManager;\r
+ \r
+ private Map<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId, MacAddress> gatewayMacAddress;\r
+\r
+ public FlowUtils(DataBroker dataBroker, ResourceManager resourceManager) {\r
+ super();\r
+\r
+ this.dataBroker = dataBroker;\r
+ this.resourceManager = resourceManager;\r
+\r
+ mplsGenerators = new HashMap<PhysicalNodeId, MplsLabelGenerator>();\r
+ meterIdGenerators = new HashMap<PhysicalNodeId, MeterIdGenerator>();\r
+ mplsLabelsOfPhysicalPaths = new HashMap<PhysicalPathId, List<Integer>>();\r
+ meterIdsOfPhysicalPaths = new HashMap<PhysicalPathId, Long>();\r
+ metadatas = new HashMap<UserId, Long>();\r
+\r
+ //liushixing\r
+ flowIdsOfUsers = new HashMap<UserId, List<InstanceIdentifier<Flow>>>();\r
+ meterIdIdsOfUsers = new HashMap<UserId, List<InstanceIdentifier<Meter>>>();\r
+// assignedPortForInPort = new ArrayList<PhysicalPortId>();\r
+\r
+ gatewayMacAddress = new HashMap<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId, MacAddress>();\r
+ // Gateway of the DMZ group.\r
+ gatewayMacAddress.put(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId("b46cfa7f-93a3-43f4-ac20-09307c75feca"),\r
+ new MacAddress("00:00:0a:0b:0c:01"));\r
+ // Gateway of the interior group.\r
+ gatewayMacAddress.put(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId("175425f7-c9c9-474a-962c-70cb6c180d4d"),\r
+ new MacAddress("00:00:0a:0b:0c:02"));\r
+ }\r
+\r
+ public void init(List<PhysicalNode> physicalNodes) {\r
+ for ( PhysicalNode physicalNode : physicalNodes ) {\r
+ mplsGenerators.put(physicalNode.getNodeId(), new MplsLabelGenerator());\r
+ meterIdGenerators.put(physicalNode.getNodeId(), new MeterIdGenerator());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param userId TODO\r
+ * @param nodeId TODO\r
+ * @param tableId TODO\r
+ * @param flowId TODO\r
+ */\r
+ private InstanceIdentifier<Flow> generateFlowInsId(UserId userId,\r
+ NodeId nodeId,\r
+ Short tableId,\r
+ FlowId flowId){\r
+\r
+\r
+ InstanceIdentifier<Flow> flowInsId = createFlowPath(nodeId, tableId, flowId);\r
+\r
+ if(flowIdsOfUsers.containsKey(userId) == false){\r
+ List<InstanceIdentifier<Flow>> flowInsIds = new ArrayList<InstanceIdentifier<Flow>>();\r
+ flowInsIds.add(flowInsId);\r
+ flowIdsOfUsers.put(userId, flowInsIds);\r
+ }else{\r
+ List<InstanceIdentifier<Flow>> flowInsIds = flowIdsOfUsers.get(userId);\r
+ flowInsIds.add(flowInsId);\r
+ }\r
+ LOG.info("nemo:generateFlowInsId");\r
+ return flowInsId;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param userId TODO\r
+ * @param nodeKey TODO\r
+ * @param meterKey TODO\r
+ */\r
+ private InstanceIdentifier<Meter> generateMeterInsId(UserId userId,\r
+ NodeKey nodeKey,\r
+ MeterKey meterKey){\r
+ InstanceIdentifier<Meter> meterInsId = InstanceIdentifier.create(Nodes.class)\r
+ .child(Node.class,nodeKey)\r
+ .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);\r
+\r
+ if(meterIdIdsOfUsers.containsKey(userId) == false){\r
+ List<InstanceIdentifier<Meter>> meterInsIds = new ArrayList<InstanceIdentifier<Meter>>();\r
+ meterInsIds.add(meterInsId);\r
+ meterIdIdsOfUsers.put(userId, meterInsIds);\r
+ }\r
+ else{\r
+ List<InstanceIdentifier<Meter>> meterInsIds = meterIdIdsOfUsers.get(userId);\r
+ meterInsIds.add(meterInsId);\r
+ }\r
+ LOG.info("nemo:getMeterInsId");\r
+ return meterInsId;\r
+ }\r
+\r
+ public void updateFlowTable(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+ //If new user, generate metadata;\r
+ if ( !metadatas.containsKey(user.getUserId()) ) {\r
+ metadatas.put(user.getUserId(), ++currentMetadata);\r
+ }\r
+\r
+ physicalNetworkHelper = new PhysicalNetworkHelper(physicalNetwork);\r
+ virtualNetworkHelper = new VirtualNetworkHelper(virtualNetwork);\r
+\r
+ updateInPortTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ updateMeterTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ updateMplsTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ updateIpTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ updateArpTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ */\r
+ public void deleteFlowEntries(UserId userId) {\r
+ deleteFlowTableEntries(userId);\r
+ deleteMeterTableEntries(userId);\r
+\r
+ flowIdsOfUsers.put(userId, new LinkedList<InstanceIdentifier<Flow>>());\r
+ meterIdIdsOfUsers.put(userId, new LinkedList<InstanceIdentifier<Meter>>());\r
+\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void close() throws Exception {\r
+ // TODO\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param physicalDestNodeId TODO\r
+ * @param physicalDestPortId TODO\r
+ */\r
+ private void configInternalInPortFlowTable(UserId userId,\r
+ PhysicalNodeId physicalDestNodeId,\r
+ PhysicalPortId physicalDestPortId) {\r
+ String nodeID = physicalDestNodeId.getValue();\r
+ String portID = physicalDestPortId.getValue();\r
+\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ Match match = new MatchBuilder().setInPort(new NodeConnectorId(portID)).build();\r
+\r
+ GoToTable gotoTable = new GoToTableBuilder().setTableId(MPLS_LABEL_TABLE_ID).build();\r
+ GoToTableCase gotoTableCase = new GoToTableCaseBuilder().setGoToTable(gotoTable).build();\r
+ Instruction instructionGoto = new InstructionBuilder().setOrder(0).setInstruction(gotoTableCase).build();\r
+ instructionList.add(instructionGoto);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(IN_PORT_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+ NodeId nodeId = new NodeId(nodeID);\r
+\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ LOG.info("nemo:configInternalInPortFlowTable");\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param physicalDestNodeId TODO\r
+ * @param physicalDestPortId TODO\r
+ * @param destNodeType TODO\r
+ */\r
+ private void configExternalInPortFlowTable(UserId userId,\r
+ PhysicalNodeId physicalDestNodeId,\r
+ PhysicalPortId physicalDestPortId,\r
+ VirtualNode.NodeType destNodeType) {\r
+ String nodeID = physicalDestNodeId.getValue();\r
+ String portID = physicalDestPortId.getValue();\r
+\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ Match match = new MatchBuilder().setInPort(new NodeConnectorId(portID)).build();\r
+\r
+ WriteMetadata writeMetadata = new WriteMetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId))).setMetadataMask(new BigInteger(DEFAULT_METADATA_MASK, 16)).build();\r
+ WriteMetadataCase writeMetadataCase = new WriteMetadataCaseBuilder().setWriteMetadata(writeMetadata).build();\r
+ Instruction instructionMeta = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(writeMetadataCase).build();\r
+ instructionList.add(instructionMeta);\r
+\r
+ GoToTable gotoTable = new GoToTableBuilder().setTableId((destNodeType==VirtualNode.NodeType.Vswitch)? MAC_TABLE_ID : IP_TABLE_ID).build();\r
+ GoToTableCase gotoTableCase = new GoToTableCaseBuilder().setGoToTable(gotoTable).build();\r
+ Instruction instructionGoto = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(gotoTableCase).build();\r
+ instructionList.add(instructionGoto);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(IN_PORT_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = new NodeId(nodeID);\r
+\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ LOG.info("nemo:configExternalInPortFlowTable");\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param user TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalNetwork TODO\r
+ */\r
+ private void updateInPortTable(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+\r
+ for(VnPnMappingResult vnPnMappingResult:vnPnMappingResults){\r
+ LOG.info("nemo:inport for(VnPnMappingResult vnPnMappingResult:vnPnMappingResults)");\r
+ if(VirtualResource.VirtualResourceType.Vport == vnPnMappingResult.getVirtualResourceType()) {\r
+ VirtualPortId virtualPortid = new VirtualPortId(vnPnMappingResult.getVirtualResourceEntityId().getValue());\r
+ VirtualNodeId virtualNodeId = new VirtualNodeId(vnPnMappingResult.getParentVirtualResourceEntityId().getValue());\r
+\r
+ VirtualPort.PortType virtualPortType = VirtualPort.PortType.Internal;\r
+ VirtualNode.NodeType virtualNodeType = VirtualNode.NodeType.Vswitch;\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ for (VirtualNode virtualNode : virtualNodes) {\r
+ if (virtualNode.getNodeId().equals(virtualNodeId)){\r
+ virtualNodeType = virtualNode.getNodeType();\r
+ for (VirtualPort virtualPort : virtualNode.getVirtualPort()) {\r
+ if (virtualPort.getPortId().equals(virtualPortid)){\r
+ virtualPortType = virtualPort.getPortType();\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ PhysicalNodeId physicalDestNodeId =\r
+ new PhysicalNodeId(vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+\r
+ PhysicalPortId physicalDestPortId =\r
+ new PhysicalPortId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+\r
+ if (virtualPortType == VirtualPort.PortType.External) {\r
+ configExternalInPortFlowTable(userVnPnMapping.getUserId(), physicalDestNodeId, physicalDestPortId, virtualNodeType);\r
+ } else {\r
+ configInternalInPortFlowTable(userVnPnMapping.getUserId(), physicalDestNodeId, physicalDestPortId);\r
+ }\r
+ }\r
+ }\r
+\r
+ for(PhysicalNode physicalNode: physicalNetwork.getPhysicalNodes().getPhysicalNode()){\r
+ PhysicalNodeId physicalDestNodeId = physicalNode.getNodeId();\r
+\r
+ for (PhysicalPort physicalPort: physicalNode.getPhysicalPort()){\r
+ PhysicalPortId physicalDestPortId = physicalPort.getPortId();\r
+ PhysicalPort.PortType physicalPortType = physicalPort.getPortType();\r
+\r
+ if(physicalPortType == PhysicalPort.PortType.Internal){\r
+ configInternalInPortFlowTable(userVnPnMapping.getUserId(), physicalDestNodeId, physicalDestPortId);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param user TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalNetwork TODO\r
+ */\r
+ private void updateMeterTable(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+\r
+ LOG.info("nemo:meter updateMeterTable()");\r
+ PhysicalPaths physicalPaths = physicalNetwork.getPhysicalPaths();\r
+ if(null == physicalPaths.getPhysicalPath()){\r
+ LOG.info("PhysicalPath are null");\r
+ return;\r
+ }\r
+\r
+ List<PhysicalPath> physicalPathList = physicalPaths.getPhysicalPath();\r
+\r
+ PhysicalLinks physicalLinks = physicalNetwork.getPhysicalLinks();\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink>\r
+ physicalLinksList = physicalLinks.getPhysicalLink();\r
+\r
+ for(PhysicalPath physicalPath:physicalPathList) {\r
+ if(physicalPath.getBandwidth() > 0 ) {\r
+ LOG.info("nemo: meter physicalPath.getBandwidth() = {}", physicalPath.getBandwidth());\r
+ if(meterIdsOfPhysicalPaths.containsKey(physicalPath.getPathId())== false){\r
+ LOG.info("nemo:meter meterIdsOfPhysicalPaths.containsKey(physicalPath.getPathId())== false");\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink\r
+ physicalLinkInPath = physicalPath.getPhysicalLink().get(0);\r
+\r
+ LOG.info("nemo:meter physicalLinkInPath"+physicalLinkInPath.getLinkId().getValue());\r
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink physicalLink : physicalLinksList) {\r
+ LOG.info("nemo:meter physicalLink "+physicalLink.getLinkId().getValue());\r
+ if (physicalLinkInPath.getLinkId().getValue().equals(physicalLink.getLinkId().getValue())) {\r
+\r
+ LOG.info("nemo:meter find plink for ppath.");\r
+ PhysicalNodeId physicalSrcNodeId = physicalLink.getSrcNodeId();\r
+ PhysicalPortId physicalSrcPortId = physicalLink.getSrcPortId();\r
+\r
+ LOG.info("nemo:meter meterIdGenerators.size() = "+ meterIdGenerators.size());\r
+ LOG.info("nemo:meter physicalSrcNodeId =" + physicalSrcNodeId.getValue());\r
+\r
+ LOG.info("nemo:meter Assign meter id");\r
+ Long meterId = (long)0;\r
+ if(meterIdGenerators.containsKey(physicalSrcNodeId) == false){\r
+ LOG.info("meterIdGenerators.containsKey(physicalSrcNodeId) == false");\r
+ MeterIdGenerator meterIdGenerator = new MeterIdGenerator();\r
+ meterIdGenerators.put(physicalSrcNodeId, meterIdGenerator);\r
+ meterId = meterIdGenerators.get(physicalSrcNodeId).generateMeterId();\r
+ meterIdsOfPhysicalPaths.put(physicalPath.getPathId(),meterId);\r
+ }\r
+ else{\r
+ LOG.info("meterIdGenerators.containsKey(physicalSrcNodeId) == true");\r
+ meterId = meterIdGenerators.get(physicalSrcNodeId).generateMeterId();\r
+ meterIdsOfPhysicalPaths.put(physicalPath.getPathId(),meterId);\r
+ }\r
+\r
+ //Generate meter flow entries\r
+ LOG.info("nemo:meter Generate meter flow entries");\r
+ NodeKey nodeKey = new NodeKey(new NodeId(physicalSrcNodeId.getValue()));\r
+ MeterKey meterKey = new MeterKey(new MeterId(meterId));\r
+\r
+ InstanceIdentifier<Meter> meterInsId = generateMeterInsId(userVnPnMapping.getUserId(), nodeKey, meterKey);\r
+\r
+ /*\r
+ MeterBandHeaderBuilder meterBandHeaderBuilder = new MeterBandHeaderBuilder();\r
+ MeterBandTypesBuilder meterBandTypesB = new MeterBandTypesBuilder();\r
+ MeterBandType bandFlag = new MeterBandType(true, false, false);\r
+ meterBandTypesB.setFlags(bandFlag);// _ofpmbtDrop\r
+ DropBuilder drop = new DropBuilder();\r
+ drop.setDropBurstSize(physicalPath.getBandwidth() / 2);\r
+ drop.setDropRate(physicalPath.getBandwidth());\r
+ Drop drp = drop.build();\r
+ meterBandHeaderBuilder.setBandType(drp);\r
+ meterBandHeaderBuilder.setMeterBandTypes(meterBandTypesB.build());\r
+ MeterBandHeader meterBH = meterBandHeaderBuilder.build();\r
+ MeterBuilder meterBuilder = new MeterBuilder();\r
+ meterBuilder.setMeterBandHeaders(meterBandHeadersBuilder.setMeterBandHeader(meterBandHeaders).build());\r
+ */\r
+\r
+ MeterBuilder meterBuilder = new MeterBuilder();\r
+ MeterBandHeaderBuilder meterBandHeaderBuilder = new MeterBandHeaderBuilder();\r
+ MeterBandHeadersBuilder meterBandHeadersBuilder = new MeterBandHeadersBuilder();\r
+ MeterBandTypesBuilder meterBandTypesB = new MeterBandTypesBuilder();\r
+\r
+ meterBandHeaderBuilder.setKey(new MeterBandHeaderKey(new BandId(physicalPath.getBandwidth())));\r
+ meterBandHeaderBuilder.setBandBurstSize((long)0);\r
+ meterBandHeaderBuilder.setBandRate(physicalPath.getBandwidth());\r
+\r
+ MeterBandType bandFlag = new MeterBandType(true, false, false);\r
+ meterBandTypesB.setFlags(bandFlag);// _ofpmbtDrop\r
+ DropBuilder drop = new DropBuilder();\r
+ drop.setDropBurstSize((long)0);\r
+ drop.setDropRate(physicalPath.getBandwidth());\r
+ Drop drp = drop.build();\r
+ meterBandHeaderBuilder.setBandType(drp);\r
+ meterBandHeaderBuilder.setMeterBandTypes(meterBandTypesB.build());\r
+\r
+ MeterBandHeader meterBH = meterBandHeaderBuilder.build();\r
+ List<MeterBandHeader> meterBandHeaders = new ArrayList<MeterBandHeader>();\r
+ meterBandHeaders.add(0, meterBH);\r
+\r
+ meterBuilder.setKey(new MeterKey(new MeterId(meterId)));\r
+ meterBuilder.setBarrier(false);\r
+\r
+ meterBuilder.setFlags(new MeterFlags(false, true, false, true));\r
+\r
+ meterBuilder.setContainerName("container." + physicalPath.getPathId());\r
+ meterBuilder.setMeterName("meter." + physicalPath.getPathId());\r
+ meterBandHeadersBuilder.setMeterBandHeader(meterBandHeaders);\r
+ meterBuilder.setMeterBandHeaders(meterBandHeadersBuilder.build());\r
+\r
+ Meter meter = meterBuilder.build();\r
+\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, meterInsId, meter);\r
+ writeTransaction.submit();\r
+ LOG.info("nemo:meter writeTransaction.submit();");\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param physicalPath TODO\r
+ * @param physicalLinksList TODO\r
+ */\r
+ public void assignMPLSLabelForPPath(PhysicalPath physicalPath,\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink> physicalLinksList){\r
+\r
+ LOG.info("nemo: for(1)");\r
+ List<Integer> mplsLabels = new ArrayList<Integer>();\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>\r
+ physicalLinksInPath = physicalPath.getPhysicalLink();\r
+\r
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink physicalLinkinPath : physicalLinksInPath) {\r
+ LOG.info("nemo: for(2)");\r
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink physicalLink : physicalLinksList) {\r
+ LOG.info("nemo: for(3)");\r
+ if (physicalLinkinPath.getLinkId().getValue().equals(physicalLink.getLinkId().getValue())) {\r
+ LOG.info("nemo: physicalLinkinPath.getLinkId() == physicalLink.getLinkId()");\r
+ PhysicalNodeId physicalDestNodeId = physicalLink.getDestNodeId();\r
+ if(mplsGenerators.containsKey(physicalDestNodeId) == true){\r
+\r
+ mplsLabels.add(mplsGenerators.get(physicalDestNodeId).generateMplsLabel());\r
+\r
+ }\r
+ else{\r
+\r
+ MplsLabelGenerator mplsLabelGenerator = new MplsLabelGenerator();\r
+ mplsGenerators.put(physicalDestNodeId, mplsLabelGenerator);\r
+ mplsLabels.add(mplsGenerators.get(physicalDestNodeId).generateMplsLabel());\r
+ }\r
+ }\r
+ }\r
+ }\r
+ mplsLabelsOfPhysicalPaths.put(physicalPath.getPathId(), mplsLabels);\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Shixing Liu\r
+ * @param user TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalNetwork TODO\r
+ */\r
+ private void updateMplsTable(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+\r
+ LOG.info("nemo:mpls: updateMplsTable()");\r
+ PhysicalPaths physicalPaths = physicalNetwork.getPhysicalPaths();\r
+\r
+ if(null == physicalPaths.getPhysicalPath()){\r
+ LOG.info("PhysicalPaths are null");\r
+ return;\r
+ }\r
+\r
+ List<PhysicalPath> physicalPathList = physicalPaths.getPhysicalPath();\r
+\r
+ PhysicalLinks physicalLinks = physicalNetwork.getPhysicalLinks();\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink>\r
+ physicalLinksList = physicalLinks.getPhysicalLink();\r
+\r
+ Iterator<Integer> mplsLabelIter = null;\r
+\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+\r
+ for(VnPnMappingResult vnPnMappingResult:vnPnMappingResults) {\r
+ if (VirtualResource.VirtualResourceType.Vlink == vnPnMappingResult.getVirtualResourceType()) {\r
+ PhysicalPathId physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ PhysicalPath physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+\r
+ VirtualLinkId virtualLinkId = new VirtualLinkId(vnPnMappingResult.getVirtualResourceEntityId().getValue());\r
+ VirtualLink virtualLink = virtualNetworkHelper.getVirtualLink(virtualLinkId);\r
+ VirtualNodeId virtualNodeId = virtualLink.getDestNodeId();\r
+ VirtualNode.NodeType nodetype = VirtualNode.NodeType.Vswitch;\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ for (VirtualNode virtualNode : virtualNodes) {\r
+ if (virtualNode.getNodeId().equals(virtualNodeId)) {\r
+ nodetype = virtualNode.getNodeType();\r
+ break;\r
+ }\r
+ }\r
+ \r
+ //Assign MPLS Label and record MPLS Label\r
+ assignMPLSLabelForPPath(physicalPath,physicalLinksList);\r
+\r
+ //Create Flow Entries for MPLS Flow Table\r
+ int counter = 0;\r
+ int inMPLSLabel = Integer.MAX_VALUE;\r
+ int outMPLSLabel = Integer.MAX_VALUE;\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>\r
+ physicalLinksInPath = physicalPath.getPhysicalLink();\r
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink physicalLinkinPath : physicalLinksInPath) {\r
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink physicalLink : physicalLinksList) {\r
+ if (physicalLinkinPath.getLinkId().getValue().equals(physicalLink.getLinkId().getValue())) {\r
+ PhysicalNodeId physicalDestNodeId = physicalLink.getDestNodeId();\r
+ PhysicalNodeId physicalSrcNodeId = physicalLink.getSrcNodeId();\r
+ PhysicalPortId physicalSrcPortId = physicalLink.getSrcPortId();\r
+\r
+ if (0 == counter++) {\r
+ LOG.info("nemo:mpls:0 == counter");\r
+ mplsLabelIter = mplsLabelsOfPhysicalPaths.get(physicalPath.getPathId()).iterator();\r
+ inMPLSLabel = mplsLabelIter.next();\r
+ } else {\r
+ LOG.info("nemo:mpls:counter="+counter);\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+ outMPLSLabel = mplsLabelIter.next();\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) ETH_TYPE_MPLS)).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ ProtocolMatchFieldsBuilder protocolMatchFieldsBuilder = new ProtocolMatchFieldsBuilder().setMplsLabel((long) inMPLSLabel);\r
+ ProtocolMatchFields protocolMatchFields = protocolMatchFieldsBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setProtocolMatchFields(protocolMatchFields).build();\r
+\r
+ SetField setField = new SetFieldBuilder().setProtocolMatchFields(new ProtocolMatchFieldsBuilder().setMplsLabel((long) outMPLSLabel).build()).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(0).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ DecMplsTtl decMplsTtl = new DecMplsTtlBuilder().build();\r
+ DecMplsTtlCase decMplsTtlCase = new DecMplsTtlCaseBuilder().setDecMplsTtl(decMplsTtl).build();\r
+ Action actionDecMPLS = new ActionBuilder().setOrder(1).setAction(decMplsTtlCase).build();\r
+ actionList.add(actionDecMPLS);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(new NodeConnectorId(physicalSrcPortId.getValue())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(2).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(0).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(MPLS_LABEL_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ LOG.info("nemo:mpls"+physicalSrcNodeId.getValue());\r
+\r
+ NodeId nodeId = new NodeId(physicalSrcNodeId.getValue());\r
+\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(user.getUserId(), nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ inMPLSLabel = outMPLSLabel;\r
+ }\r
+ //The last hop\r
+ if (physicalPath.getPhysicalLink().size() == counter) {\r
+ LOG.info("nemo:mpls: last hop");\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long) ETH_TYPE_MPLS)).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ ProtocolMatchFieldsBuilder protocolMatchFieldsBuilder = new ProtocolMatchFieldsBuilder().setMplsLabel((long) inMPLSLabel);\r
+ ProtocolMatchFields protocolMatchFields = protocolMatchFieldsBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setProtocolMatchFields(protocolMatchFields).build();\r
+\r
+ PopMplsAction popMplsAction = new PopMplsActionBuilder().setEthernetType(ETH_TYPE_IP).build();\r
+ PopMplsActionCase popMplsActionCase = new PopMplsActionCaseBuilder().setPopMplsAction(popMplsAction).build();\r
+ Action actionPopMPLS = new ActionBuilder().setOrder(0).setAction(popMplsActionCase).build();\r
+ actionList.add(actionPopMPLS);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(0).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ WriteMetadata writeMetadata = new WriteMetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(user.getUserId()))).setMetadataMask(new BigInteger(DEFAULT_METADATA_MASK, 16)).build();\r
+ WriteMetadataCase writeMetadataCase = new WriteMetadataCaseBuilder().setWriteMetadata(writeMetadata).build();\r
+ Instruction instructionMeta = new InstructionBuilder().setOrder(1).setInstruction(writeMetadataCase).build();\r
+ instructionList.add(instructionMeta);\r
+\r
+ GoToTable gotoTable = new GoToTableBuilder().setTableId((nodetype == VirtualNode.NodeType.Vswitch)? MAC_TABLE_ID:IP_TABLE_ID).build();\r
+ GoToTableCase gotoTableCase = new GoToTableCaseBuilder().setGoToTable(gotoTable).build();\r
+ Instruction instructionGoto = new InstructionBuilder().setOrder(2).setInstruction(gotoTableCase).build();\r
+ instructionList.add(instructionGoto);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(MPLS_LABEL_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ LOG.info("nemo:mpls:"+physicalDestNodeId.getValue());\r
+ NodeId nodeId = new NodeId(physicalDestNodeId.getValue());\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(user.getUserId(), nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param user TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalNetwork TODO\r
+ */\r
+ private void updateIpTable(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+ Map<VirtualNodeId, VirtualNode> virtualRouters = virtualNetworkHelper.getVirtualRouters();\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> connectedVirtualSwitches;\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> connectedVirtualSwitches1;\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> connectedVirtualRouters;\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> connectedVirtualRouters1;\r
+ VirtualPort layer2ExternalVirtualPort;\r
+ VirtualPort layer2ExternalVirtualPort1;\r
+ VirtualPort layer2ExternalVirtualPort2;\r
+ VirtualPort layer3ExternalVirtualPort;\r
+ VirtualPort layer3ExternalVirtualPort1;\r
+ VnPnMappingResult vnPnMappingResult;\r
+ PhysicalNodeId physicalNodeId;\r
+ PhysicalNodeId physicalNodeId1;\r
+ VirtualLink virtualLink;\r
+ VirtualLink virtualLink1;\r
+ PhysicalPathId physicalPathId;\r
+ PhysicalPathId physicalPathId1;\r
+ PhysicalPath physicalPath;\r
+ PhysicalPath physicalPath1;\r
+ PhysicalPortId physicalPortId;\r
+ PhysicalPort physicalPort;\r
+ List<IpPrefix> remoteIpPrefixes;\r
+ List<IpPrefix> ipPrefixes;\r
+ List<MacAddress> macAddresses;\r
+ VirtualPort virtualPort;\r
+ VirtualArp virtualArp;\r
+ IpPrefix ipPrefix;\r
+ MacAddress gatewayMacAddress;\r
+\r
+ for ( VirtualNodeId virtualNodeId : virtualRouters.keySet() ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualNodeId.getValue()));\r
+ physicalNodeId = new PhysicalNodeId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+\r
+ connectedVirtualRouters = virtualNetworkHelper.getConnectedVirtualRouters(virtualNodeId);\r
+\r
+ if ( null != connectedVirtualRouters ) {\r
+ for ( Map.Entry<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> entry\r
+ : connectedVirtualRouters.entrySet() ) {\r
+ virtualLink = entry.getValue().getValue();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLink.getLinkId().getValue()));\r
+ physicalPathId = new PhysicalPathId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+ remoteIpPrefixes = new LinkedList<IpPrefix>();\r
+\r
+ connectedVirtualSwitches1 = virtualNetworkHelper\r
+ .getConnectedVirtualSwitches(entry.getKey());\r
+\r
+ if ( null != connectedVirtualSwitches1 ) {\r
+ virtualPort = connectedVirtualSwitches1.entrySet().iterator().next().getValue().getKey();\r
+ ipPrefix = virtualPort.getExternalIpPrefixes().getExternalIpPrefix().get(0);\r
+ remoteIpPrefixes.add(ipPrefix);\r
+ }\r
+\r
+ layer3ExternalVirtualPort1 = virtualNetworkHelper\r
+ .getLayer3ExternalVirtualPort(entry.getKey());\r
+\r
+ if ( null != layer3ExternalVirtualPort1 ) {\r
+ remoteIpPrefixes.addAll(\r
+ layer3ExternalVirtualPort1.getExternalIpPrefixes().getExternalIpPrefix());\r
+ }\r
+\r
+ layer2ExternalVirtualPort1 = virtualNetworkHelper\r
+ .getLayer2ExternalVirtualPort(entry.getKey());\r
+\r
+ if ( null != layer2ExternalVirtualPort1 ) {\r
+ remoteIpPrefixes.addAll(\r
+ layer2ExternalVirtualPort1.getExternalIpPrefixes().getExternalIpPrefix());\r
+ }\r
+\r
+ if ( !physicalPath.getPhysicalLink().isEmpty() ) {\r
+ for ( IpPrefix ipPrefix1 : remoteIpPrefixes ) {\r
+ configIpTableEntry(user.getUserId(), ipPrefix1, physicalPath, false);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ connectedVirtualSwitches = virtualNetworkHelper.getConnectedVirtualSwitches(virtualNodeId);\r
+\r
+ if ( null != connectedVirtualSwitches ) {\r
+ virtualPort = connectedVirtualSwitches.values().iterator().next().getKey();\r
+ ipPrefix = virtualPort.getExternalIpPrefixes().getExternalIpPrefix().get(0);\r
+ gatewayMacAddress = getGateWayMacAddress(userIntentVnMapping, virtualNodeId);\r
+\r
+ configIpTableEntry(user.getUserId(), ipPrefix, gatewayMacAddress, physicalNodeId);\r
+\r
+ for ( Map.Entry<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> entry\r
+ : connectedVirtualSwitches.entrySet() ) {\r
+ virtualLink = entry.getValue().getValue();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLink.getLinkId().getValue()));\r
+ physicalPathId = new PhysicalPathId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+\r
+ connectedVirtualRouters1 = virtualNetworkHelper\r
+ .getConnectedVirtualRouters(entry.getKey());\r
+\r
+ if ( null != connectedVirtualRouters1 ) {\r
+ virtualLink1 = connectedVirtualRouters1.values().iterator().next().getValue();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()));\r
+ physicalPathId1 = new PhysicalPathId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath1 = physicalNetworkHelper.getPhysicalPath(physicalPathId1);\r
+\r
+ configMacTableEntry(user.getUserId(), gatewayMacAddress, physicalPath1);\r
+ }\r
+\r
+ connectedVirtualSwitches1 = virtualNetworkHelper\r
+ .getConnectedVirtualSwitches(entry.getKey());\r
+\r
+ if ( null != connectedVirtualSwitches1 ) {\r
+ for ( Map.Entry<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> entry1\r
+ : connectedVirtualSwitches1.entrySet() ) {\r
+ virtualLink1 = entry1.getValue().getValue();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLink1.getLinkId().getValue()));\r
+ physicalPathId1 = new PhysicalPathId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath1 = physicalNetworkHelper.getPhysicalPath(physicalPathId1);\r
+\r
+ if ( !physicalPath1.getPhysicalLink().isEmpty() ) {\r
+ layer2ExternalVirtualPort2 = virtualNetworkHelper\r
+ .getLayer2ExternalVirtualPort(entry1.getKey());\r
+\r
+ if ( null != layer2ExternalVirtualPort2 ) {\r
+ macAddresses = layer2ExternalVirtualPort2\r
+ .getExternalMacAddresses().getExternalMacAddress();\r
+\r
+ for ( MacAddress macAddress : macAddresses ) {\r
+ configMacTableEntry(user.getUserId(), macAddress, physicalPath1);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ layer2ExternalVirtualPort1 = virtualNetworkHelper\r
+ .getLayer2ExternalVirtualPort(entry.getKey());\r
+\r
+ if ( null != layer2ExternalVirtualPort1 ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(layer2ExternalVirtualPort1.getPortId().getValue()));\r
+ physicalNodeId1 = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId1, physicalPortId);\r
+\r
+ macAddresses = layer2ExternalVirtualPort1\r
+ .getExternalMacAddresses().getExternalMacAddress();\r
+\r
+ for ( MacAddress macAddress : macAddresses ) {\r
+ virtualArp = virtualNetworkHelper.getVirtualArp(macAddress);\r
+\r
+ configArpTableEntry(user.getUserId(), virtualArp, physicalPath);\r
+ configMacTableEntry(user.getUserId(), macAddress, physicalNodeId1, physicalPort);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ layer3ExternalVirtualPort = virtualNetworkHelper.getLayer3ExternalVirtualPort(virtualNodeId);\r
+\r
+ if ( null != layer3ExternalVirtualPort ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(layer3ExternalVirtualPort.getPortId().getValue()));\r
+ physicalPortId = new PhysicalPortId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ ipPrefixes = layer3ExternalVirtualPort.getExternalIpPrefixes().getExternalIpPrefix();\r
+\r
+ for ( IpPrefix ipPrefix1 : ipPrefixes ) {\r
+ configIpTableEntry(user.getUserId(), ipPrefix1, physicalNodeId, physicalPort, false);\r
+ }\r
+ }\r
+\r
+ layer2ExternalVirtualPort = virtualNetworkHelper.getLayer2ExternalVirtualPort(virtualNodeId);\r
+\r
+ if ( null != layer2ExternalVirtualPort ) {\r
+ // TODO: config ip and arp tables.\r
+ }\r
+ }\r
+\r
+ updateIpTableForOperations(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
+\r
+ // for testing - jizhigang\r
+ // log format: vnode(nodetype) --> vnode(nodetype): vlink; ppath; plinks; mplslabels; meterid;\r
+ Set<VirtualLinkId> printedVirtualLinks = new HashSet<VirtualLinkId>();\r
+ VirtualNode srcVirtualNode;\r
+ VirtualNode dstVirtualNode;\r
+ PhysicalPath physicalPath2;\r
+\r
+ for ( VirtualLink virtualLink2 : virtualNetwork.getVirtualLinks().getVirtualLink() ) {\r
+ if ( !printedVirtualLinks.contains(virtualLink2.getLinkId()) ) {\r
+ srcVirtualNode = virtualNetworkHelper.virtualNodeMap.get(virtualLink2.getSrcNodeId());\r
+ dstVirtualNode = virtualNetworkHelper.virtualNodeMap.get(virtualLink2.getDestNodeId());\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults, new VirtualResourceEntityId(virtualLink2.getLinkId().getValue()));\r
+ physicalPath2 = physicalNetworkHelper.getPhysicalPath(new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue()));\r
+\r
+ System.out.println(srcVirtualNode.getNodeId().getValue() + "(" + srcVirtualNode.getNodeType() + ") --> " +\r
+ dstVirtualNode.getNodeId().getValue() + "(" + dstVirtualNode.getNodeType() + "): " + virtualLink2.getLinkId().getValue() + "; " +\r
+ physicalPath2.getPathId().getValue() + "; " + physicalPath2.getPhysicalLink() + "; " +\r
+ mplsLabelsOfPhysicalPaths.get(physicalPath2.getPathId()) + "; " +\r
+ meterIdsOfPhysicalPaths.get(physicalPath2.getPathId()) + ";");\r
+\r
+ for ( VirtualLink virtualLink3 : virtualNetwork.getVirtualLinks().getVirtualLink() ) {\r
+ if ( virtualLink3.getSrcNodeId().equals(dstVirtualNode.getNodeId())\r
+ && virtualLink3.getDestNodeId().equals(srcVirtualNode.getNodeId()) ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults, new VirtualResourceEntityId(virtualLink3.getLinkId().getValue()));\r
+ physicalPath2 = physicalNetworkHelper.getPhysicalPath(new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue()));\r
+\r
+ System.out.println(dstVirtualNode.getNodeId().getValue() + "(" + dstVirtualNode.getNodeType() + ") --> " +\r
+ srcVirtualNode.getNodeId().getValue() + "(" + srcVirtualNode.getNodeType() + "): " + virtualLink3.getLinkId().getValue() + "; " +\r
+ physicalPath2.getPathId().getValue() + "; " + physicalPath2.getPhysicalLink() + "; " +\r
+ mplsLabelsOfPhysicalPaths.get(physicalPath2.getPathId()) + "; " +\r
+ meterIdsOfPhysicalPaths.get(physicalPath2.getPathId()) + ";");\r
+\r
+ printedVirtualLinks.add(virtualLink3.getLinkId());\r
+ }\r
+ }\r
+\r
+ printedVirtualLinks.add(virtualLink2.getLinkId());\r
+ }\r
+ }\r
+ // for testing - jizhigang\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param user TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalNetwork TODO\r
+ */\r
+ private void updateArpTable(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+ // TODO\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ */\r
+ private void deleteFlowTableEntries(UserId userId) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+\r
+ for ( InstanceIdentifier<Flow> flowIid : flowIdsOfUsers.get(userId) ) {\r
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, flowIid);\r
+ }\r
+\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ */\r
+ private void deleteMeterTableEntries(UserId userId) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+\r
+ for ( InstanceIdentifier<Meter> meterIid : meterIdIdsOfUsers.get(userId) ) {\r
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, meterIid);\r
+ }\r
+\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param user TODO\r
+ * @param virtualNetwork TODO\r
+ * @param userIntentVnMapping TODO\r
+ * @param userVnPnMapping TODO\r
+ * @param physicalNetwork TODO\r
+ */\r
+ private void updateIpTableForOperations(User user,\r
+ VirtualNetwork virtualNetwork,\r
+ UserIntentVnMapping userIntentVnMapping,\r
+ UserVnPnMapping userVnPnMapping,\r
+ PhysicalNetwork physicalNetwork) {\r
+ if ( null == user.getOperations() ) {\r
+ return;\r
+ }\r
+\r
+ List<Operation> operations = user.getOperations().getOperation();\r
+\r
+ if ( null == operations || operations.isEmpty() ) {\r
+ return;\r
+ }\r
+\r
+ Operation operation = operations.get(0);\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow> nemoFlows =\r
+ user.getObjects().getFlow();\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.FlowId nemoFlowId =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.FlowId(operation.getTargetObject().getValue());\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow nemoFlow =\r
+ getFlow(nemoFlows, nemoFlowId);\r
+\r
+ long priority = 1 + operation.getPriority();\r
+\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
+ IntentId intentId = new IntentId(operation.getOperationId().getValue());\r
+ IntentVnMappingResult intentVnMappingResult = getIntentVnMappingResult(intentVnMappingResults, intentId);\r
+ List<VirtualResource> virtualResources = sortVirtualResources(intentVnMappingResult.getVirtualResource());\r
+ Iterator<VirtualResource> iterator = virtualResources.iterator();\r
+ VirtualResource virtualResource;\r
+ VirtualResource virtualResource1 = null;\r
+ VirtualPathId virtualPathId;\r
+ VirtualPath virtualPath;\r
+ VirtualLinkId virtualLinkId;\r
+ VirtualLink virtualLink;\r
+ VirtualNodeId virtualNodeId;\r
+ VnPnMappingResult vnPnMappingResult;\r
+\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> connectedVirtualSwitches;\r
+ VirtualPort layer2ExternalVirtualPort;\r
+ VirtualPort layer3ExternalVirtualPort;\r
+\r
+ PhysicalPathId physicalPathId;\r
+ PhysicalPathId physicalPathId1;\r
+ PhysicalPath physicalPath;\r
+ PhysicalPath physicalPath1;\r
+ PhysicalNodeId physicalNodeId;\r
+ PhysicalNodeId physicalNodeId1;\r
+ PhysicalPortId physicalPortId;\r
+ PhysicalPortId physicalPortId1;\r
+ PhysicalLink physicalLink;\r
+ PhysicalPort physicalPort;\r
+ PhysicalPort physicalPort1;\r
+\r
+ while ( iterator.hasNext() ) {\r
+ virtualResource = iterator.next();\r
+\r
+ if ( null == virtualResource1 ) {\r
+ if ( VirtualResource.VirtualResourceType.Vpath\r
+ == virtualResource.getVirtualResourceType() ) {\r
+ virtualPathId = new VirtualPathId(virtualResource.getVirtualResourceEntityId().getValue());\r
+ virtualPath = virtualNetworkHelper.getVirtualPath(virtualPathId);\r
+ virtualLinkId = virtualPath.getVirtualLink().get(0).getLinkId();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLinkId.getValue()));\r
+ physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+\r
+ if ( physicalPath.getPhysicalLink().isEmpty() ) {\r
+ continue;\r
+ } else {\r
+ virtualLink = virtualNetworkHelper.getVirtualLink(virtualLinkId);\r
+ connectedVirtualSwitches = virtualNetworkHelper\r
+ .getConnectedVirtualSwitches(virtualLink.getSrcNodeId());\r
+\r
+ if ( null != connectedVirtualSwitches ) {\r
+ for ( Map.Entry<VirtualPort, VirtualLink> entry : connectedVirtualSwitches.values() ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(entry.getValue().getLinkId().getValue()));\r
+ physicalPathId1 = new PhysicalPathId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath1 = physicalNetworkHelper.getPhysicalPath(physicalPathId1);\r
+ physicalLink = physicalNetworkHelper\r
+ .getFirstPhysicalLinkOfPhysicalPath(physicalPath1);\r
+ physicalPort = physicalNetworkHelper\r
+ .getPhysicalPort(physicalLink.getSrcNodeId(), physicalLink.getSrcPortId());\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalPort, physicalPath, (short)priority, true);\r
+ }\r
+ }\r
+\r
+ layer3ExternalVirtualPort = virtualNetworkHelper\r
+ .getLayer3ExternalVirtualPort(virtualLink.getSrcNodeId());\r
+\r
+ if ( null != layer3ExternalVirtualPort ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(layer3ExternalVirtualPort.getPortId().getValue()));\r
+ physicalNodeId = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalPort, physicalPath, (short)priority, true);\r
+ }\r
+\r
+ layer2ExternalVirtualPort = virtualNetworkHelper\r
+ .getLayer2ExternalVirtualPort(virtualLink.getSrcNodeId());\r
+\r
+ if ( null != layer2ExternalVirtualPort ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(layer2ExternalVirtualPort.getPortId().getValue()));\r
+ physicalNodeId = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalPort, physicalPath, (short)priority, true);\r
+ }\r
+ }\r
+ } else if ( VirtualResource.VirtualResourceType.Vport\r
+ == virtualResource.getVirtualResourceType() ) {\r
+ virtualNodeId = new VirtualNodeId(virtualResource.getParentVirtualResourceEntityId().getValue());\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualResource.getVirtualResourceEntityId().getValue()));\r
+ physicalNodeId = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ connectedVirtualSwitches = virtualNetworkHelper.getConnectedVirtualSwitches(virtualNodeId);\r
+\r
+ if ( null != connectedVirtualSwitches ) {\r
+ for ( Map.Entry<VirtualPort, VirtualLink> entry : connectedVirtualSwitches.values() ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(entry.getValue().getLinkId().getValue()));\r
+ physicalPathId = new PhysicalPathId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+ physicalLink = physicalNetworkHelper\r
+ .getFirstPhysicalLinkOfPhysicalPath(physicalPath);\r
+ physicalPort1 = physicalNetworkHelper\r
+ .getPhysicalPort(physicalLink.getSrcNodeId(), physicalLink.getSrcPortId());\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalNodeId, physicalPort1, physicalPort, (short)priority, true);\r
+ }\r
+ }\r
+\r
+ layer3ExternalVirtualPort = virtualNetworkHelper.getLayer3ExternalVirtualPort(virtualNodeId);\r
+\r
+ if ( null != layer3ExternalVirtualPort ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(layer3ExternalVirtualPort.getPortId().getValue()));\r
+ physicalNodeId1 = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId1 = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort1 = physicalNetworkHelper.getPhysicalPort(physicalNodeId1, physicalPortId1);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalNodeId1, physicalPort1, physicalPort, (short)priority, true);\r
+ }\r
+\r
+ layer2ExternalVirtualPort = virtualNetworkHelper.getLayer2ExternalVirtualPort(virtualNodeId);\r
+\r
+ if ( null != layer2ExternalVirtualPort ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(layer2ExternalVirtualPort.getPortId().getValue()));\r
+ physicalNodeId1 = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId1 = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort1 = physicalNetworkHelper.getPhysicalPort(physicalNodeId1, physicalPortId1);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalNodeId1, physicalPort1, physicalPort, (short)priority, true);\r
+ }\r
+ }\r
+ } else {\r
+ if ( VirtualResource.VirtualResourceType.Vport == virtualResource1.getVirtualResourceType()\r
+ && VirtualResource.VirtualResourceType.Vpath == virtualResource.getVirtualResourceType() ) {\r
+ virtualPathId = new VirtualPathId(virtualResource.getVirtualResourceEntityId().getValue());\r
+ virtualPath = virtualNetworkHelper.getVirtualPath(virtualPathId);\r
+ virtualLinkId = virtualPath.getVirtualLink().get(0).getLinkId();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLinkId.getValue()));\r
+ physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+\r
+ if ( physicalPath.getPhysicalLink().isEmpty() ) {\r
+ continue;\r
+ } else {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualResource1.getVirtualResourceEntityId().getValue()));\r
+ physicalNodeId = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalPort, physicalPath, (short)priority, true);\r
+ }\r
+ } else if ( VirtualResource.VirtualResourceType.Vpath == virtualResource1.getVirtualResourceType()\r
+ && VirtualResource.VirtualResourceType.Vport == virtualResource.getVirtualResourceType() ) {\r
+ virtualPathId = new VirtualPathId(virtualResource1.getVirtualResourceEntityId().getValue());\r
+ virtualPath = virtualNetworkHelper.getVirtualPath(virtualPathId);\r
+ virtualLinkId = virtualPath.getVirtualLink().get(0).getLinkId();\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualLinkId.getValue()));\r
+ physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPath = physicalNetworkHelper.getPhysicalPath(physicalPathId);\r
+ physicalLink = physicalNetworkHelper.getLastPhysicalLinkOfPhysicalPath(physicalPath);\r
+ physicalPort1 = physicalNetworkHelper\r
+ .getPhysicalPort(physicalLink.getDestNodeId(), physicalLink.getDestPortId());\r
+\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualResource.getVirtualResourceEntityId().getValue()));\r
+ physicalNodeId = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalNodeId, physicalPort1, physicalPort, (short)priority, true);\r
+ } else if ( VirtualResource.VirtualResourceType.Vport == virtualResource1.getVirtualResourceType()\r
+ && VirtualResource.VirtualResourceType.Vport == virtualResource.getVirtualResourceType() ) {\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualResource1.getVirtualResourceEntityId().getValue()));\r
+ physicalNodeId1 = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId1 = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort1 = physicalNetworkHelper.getPhysicalPort(physicalNodeId1, physicalPortId1);\r
+\r
+ vnPnMappingResult = getVnPnMappingResult(vnPnMappingResults,\r
+ new VirtualResourceEntityId(virtualResource.getVirtualResourceEntityId().getValue()));\r
+ physicalNodeId = new PhysicalNodeId(\r
+ vnPnMappingResult.getParentPhysicalResourceEntityId().getValue());\r
+ physicalPortId = new PhysicalPortId(\r
+ vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
+ physicalPort = physicalNetworkHelper.getPhysicalPort(physicalNodeId, physicalPortId);\r
+\r
+ configIpTableEntryForOperation(user.getUserId(), nemoFlow,\r
+ physicalNodeId1, physicalPort1, physicalPort, (short)priority, true);\r
+ }\r
+ }\r
+\r
+ virtualResource1 = virtualResource;\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji, Shixing Liu\r
+ * @param physicalNodeId TODO\r
+ * @param physicalPortId TODO\r
+ * @return TODO\r
+ */\r
+ private MacAddress getMacAddressOfConnectedExternalDevice(PhysicalNodeId physicalNodeId,\r
+ PhysicalPortId physicalPortId) {\r
+ com.google.common.collect.Table<PhysicalNodeId, PhysicalPortId, MacAddress> externalNetworkMacTable =\r
+ this.resourceManager.getExternalNetworkMacTable();\r
+\r
+ MacAddress macAddress = externalNetworkMacTable.get(physicalNodeId, physicalPortId);\r
+ if(macAddress == null){\r
+ LOG.info("nemo: cannot find external network device mac address");\r
+ }\r
+ LOG.info("nemo: external network device mac address");\r
+\r
+ return macAddress;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userIntentVnMapping TODO\r
+ * @param virtualNodeId TODO\r
+ * @return TODO\r
+ */\r
+ private MacAddress getGateWayMacAddress(UserIntentVnMapping userIntentVnMapping,\r
+ VirtualNodeId virtualNodeId) {\r
+ List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();\r
+ VirtualResource virtualResource;\r
+\r
+ for ( IntentVnMappingResult intentVnMappingResult : intentVnMappingResults ) {\r
+ virtualResource = intentVnMappingResult.getVirtualResource().get(0);\r
+\r
+ if ( virtualResource.getVirtualResourceEntityId().getValue().equals(virtualNodeId.getValue()) ) {\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId nodeId =\r
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId(intentVnMappingResult.getIntentId().getValue());\r
+\r
+ return gatewayMacAddress.get(nodeId);\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param flows TODO\r
+ * @param flowId TODO\r
+ * @return TODO\r
+ */\r
+ private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow getFlow(\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow> flows,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.FlowId flowId) {\r
+ for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow\r
+ flow : flows ) {\r
+ if ( flow.getFlowId().equals(flowId) ) {\r
+ return flow;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param matchItems TODO\r
+ * @param matchItemName TODO\r
+ * @return TODO\r
+ */\r
+ private MatchItem getMatchItem(List<MatchItem> matchItems, MatchItemName matchItemName) {\r
+ for ( MatchItem matchItem : matchItems ) {\r
+ if ( matchItem.getMatchItemName().equals(matchItemName) ) {\r
+ return matchItem;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param intentVnMappingResults TODO\r
+ * @param intentId TODO\r
+ * @return TODO\r
+ */\r
+ private IntentVnMappingResult getIntentVnMappingResult(\r
+ List<IntentVnMappingResult> intentVnMappingResults, IntentId intentId) {\r
+ for ( IntentVnMappingResult intentVnMappingResult : intentVnMappingResults ) {\r
+ if ( intentVnMappingResult.getIntentId().equals(intentId) ) {\r
+ return intentVnMappingResult;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param vnPnMappingResults TODO\r
+ * @param virtualResourceEntityId TODO\r
+ * @return TODO\r
+ */\r
+ private VnPnMappingResult getVnPnMappingResult(List<VnPnMappingResult> vnPnMappingResults,\r
+ VirtualResourceEntityId virtualResourceEntityId) {\r
+ for ( VnPnMappingResult vnPnMappingResult : vnPnMappingResults ) {\r
+ if ( vnPnMappingResult.getVirtualResourceEntityId().equals(virtualResourceEntityId) ) {\r
+ return vnPnMappingResult;\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param virtualResources TODO\r
+ * @return TODO\r
+ */\r
+ private List<VirtualResource> sortVirtualResources(List<VirtualResource> virtualResources) {\r
+ if ( null == virtualResources || 2 > virtualResources.size() ) {\r
+ return virtualResources;\r
+ }\r
+\r
+ List<VirtualResource> sortedVirtualResources =\r
+ new ArrayList<VirtualResource>(virtualResources.size());\r
+ sortedVirtualResources.addAll(virtualResources);\r
+\r
+ for ( VirtualResource virtualResource : virtualResources ) {\r
+ sortedVirtualResources.set(virtualResource.getOrder().intValue(), virtualResource);\r
+ }\r
+\r
+ return sortedVirtualResources;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param macAddress TODO\r
+ * @param physicalNodeId TODO\r
+ * @param physicalPort TODO\r
+ */\r
+ private void configMacTableEntry(UserId userId, MacAddress macAddress,\r
+ PhysicalNodeId physicalNodeId, PhysicalPort physicalPort) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetDestination(new EthernetDestinationBuilder().setAddress(macAddress).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ MetadataBuilder metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ Metadata metadata = metadataBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setMetadata(metadata).build();\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(physicalPort.getPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(MAC_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalNodeId);\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param macAddress TODO\r
+ * @param physicalPath TODO\r
+ */\r
+ private void configMacTableEntry(UserId userId, MacAddress macAddress,\r
+ PhysicalPath physicalPath) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ PhysicalLink physicalLink = physicalNetworkHelper.getFirstPhysicalLinkOfPhysicalPath(physicalPath);\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetDestination(new EthernetDestinationBuilder().setAddress(macAddress).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ MetadataBuilder metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ Metadata metadata = metadataBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setMetadata(metadata).build();\r
+\r
+ PushMplsAction pushMplsAction = new PushMplsActionBuilder().setEthernetType(ETH_TYPE_MPLS).build();\r
+ PushMplsActionCase pushMplsActionCase = new PushMplsActionCaseBuilder().setPushMplsAction(pushMplsAction).build();\r
+ Action actionPushMPLS = new ActionBuilder().setOrder(actionList.size()).setAction(pushMplsActionCase).build();\r
+ actionList.add(actionPushMPLS);\r
+\r
+ SetField setField = new SetFieldBuilder().setProtocolMatchFields(new ProtocolMatchFieldsBuilder().setMplsLabel((long)mplsLabelsOfPhysicalPaths.get(physicalPath.getPathId()).get(0)).build()).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(physicalLink.getSrcPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(MAC_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalLink.getSrcNodeId());\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param ipPrefix TODO\r
+ * @param physicalNodeId TODO\r
+ * @param physicalPort TODO\r
+ * @param goToArpTable TODO\r
+ */\r
+ private void configIpTableEntry(UserId userId, IpPrefix ipPrefix, PhysicalNodeId physicalNodeId,\r
+ PhysicalPort physicalPort, boolean goToArpTable) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long)ETH_TYPE_IP)).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ MetadataBuilder metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ Metadata metadata = metadataBuilder.build();\r
+\r
+ Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder().setIpv4Destination(ipPrefix.getIpv4Prefix());\r
+ Ipv4Match ipv4Match = ipv4MatchBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setMetadata(metadata).setLayer3Match(ipv4Match).build();\r
+\r
+ DecNwTtl decNwTtl = new DecNwTtlBuilder().build();\r
+ DecNwTtlCase decNwTtlCase = new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build();\r
+ Action actionDecNW = new ActionBuilder().setOrder(actionList.size()).setAction(decNwTtlCase).build();\r
+ actionList.add(actionDecNW);\r
+\r
+ ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetSource(new EthernetSourceBuilder().setAddress(physicalPort.getMacAddress()).build());\r
+ ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ SetField setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ if ( goToArpTable )\r
+ {\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ WriteMetadata writeMetadata = new WriteMetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId))).setMetadataMask(new BigInteger(DEFAULT_METADATA_MASK, 16)).build();\r
+ WriteMetadataCase writeMetadataCase = new WriteMetadataCaseBuilder().setWriteMetadata(writeMetadata).build();\r
+ Instruction instructionMeta = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(writeMetadataCase).build();\r
+ instructionList.add(instructionMeta);\r
+\r
+ GoToTable gotoTable = new GoToTableBuilder().setTableId(ARP_TABLE_ID).build();\r
+ GoToTableCase gotoTableCase = new GoToTableCaseBuilder().setGoToTable(gotoTable).build();\r
+ Instruction instructionGoto = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(gotoTableCase).build();\r
+ instructionList.add(instructionGoto);\r
+ }\r
+ else\r
+ {\r
+ ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetDestination(new EthernetDestinationBuilder().setAddress(getMacAddressOfConnectedExternalDevice(physicalNodeId, physicalPort.getPortId())).build());\r
+ ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(physicalPort.getPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+ }\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(IP_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalNodeId);\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param ipPrefix TODO\r
+ * @param physicalPath TODO\r
+ * @param goToArpTable TODO\r
+ */\r
+ private void configIpTableEntry(UserId userId, IpPrefix ipPrefix,\r
+ PhysicalPath physicalPath, boolean goToArpTable) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ PhysicalLink physicalLink = physicalNetworkHelper.getFirstPhysicalLinkOfPhysicalPath(physicalPath);\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long)ETH_TYPE_IP)).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ MetadataBuilder metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ Metadata metadata = metadataBuilder.build();\r
+\r
+ Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder().setIpv4Destination(ipPrefix.getIpv4Prefix());\r
+ Ipv4Match ipv4Match = ipv4MatchBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setMetadata(metadata).setLayer3Match(ipv4Match).build();\r
+\r
+ if ( 0 < physicalPath.getBandwidth() ) {\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.Meter\r
+ meter = new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.MeterBuilder()\r
+ .setMeterId(new MeterId(meterIdsOfPhysicalPaths.get(physicalPath.getPathId()))).build();\r
+ MeterCase meterCase = new MeterCaseBuilder().setMeter(meter).build();\r
+ Instruction instructionMeter = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(meterCase).build();\r
+ instructionList.add(instructionMeter);\r
+ }\r
+\r
+ DecNwTtl decNwTtl = new DecNwTtlBuilder().build();\r
+ DecNwTtlCase decNwTtlCase = new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build();\r
+ Action actionDecNW = new ActionBuilder().setOrder(actionList.size()).setAction(decNwTtlCase).build();\r
+ actionList.add(actionDecNW);\r
+\r
+ if ( goToArpTable )\r
+ {\r
+ PhysicalPort physicalPort = physicalNetworkHelper.getPhysicalPort(physicalLink.getSrcNodeId(), physicalLink.getSrcPortId());\r
+\r
+ ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetSource(new EthernetSourceBuilder().setAddress(physicalPort.getMacAddress()).build());\r
+ ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ SetField setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ WriteMetadata writeMetadata = new WriteMetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId))).setMetadataMask(new BigInteger(DEFAULT_METADATA_MASK, 16)).build();\r
+ WriteMetadataCase writeMetadataCase = new WriteMetadataCaseBuilder().setWriteMetadata(writeMetadata).build();\r
+ Instruction instructionMeta = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(writeMetadataCase).build();\r
+ instructionList.add(instructionMeta);\r
+\r
+ GoToTable gotoTable = new GoToTableBuilder().setTableId(ARP_TABLE_ID).build();\r
+ GoToTableCase gotoTableCase = new GoToTableCaseBuilder().setGoToTable(gotoTable).build();\r
+ Instruction instructionGoto = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(gotoTableCase).build();\r
+ instructionList.add(instructionGoto);\r
+ }\r
+ else\r
+ {\r
+ PushMplsAction pushMplsAction = new PushMplsActionBuilder().setEthernetType(ETH_TYPE_MPLS).build();\r
+ PushMplsActionCase pushMplsActionCase = new PushMplsActionCaseBuilder().setPushMplsAction(pushMplsAction).build();\r
+ Action actionPushMPLS = new ActionBuilder().setOrder(actionList.size()).setAction(pushMplsActionCase).build();\r
+ actionList.add(actionPushMPLS);\r
+\r
+ SetField setField = new SetFieldBuilder().setProtocolMatchFields(new ProtocolMatchFieldsBuilder().setMplsLabel((long)mplsLabelsOfPhysicalPaths.get(physicalPath.getPathId()).get(0)).build()).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(physicalLink.getSrcPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+ }\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(IP_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalLink.getSrcNodeId());\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param ipPrefix TODO\r
+ * @param macAddress TODO\r
+ * @param physicalNodeId TODO\r
+ */\r
+ private void configIpTableEntry(UserId userId, IpPrefix ipPrefix,\r
+ MacAddress macAddress, PhysicalNodeId physicalNodeId) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long)ETH_TYPE_IP)).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ MetadataBuilder metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ Metadata metadata = metadataBuilder.build();\r
+\r
+ Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder().setIpv4Destination(ipPrefix.getIpv4Prefix());\r
+ Ipv4Match ipv4Match = ipv4MatchBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setMetadata(metadata).setLayer3Match(ipv4Match).build();\r
+\r
+ DecNwTtl decNwTtl = new DecNwTtlBuilder().build();\r
+ DecNwTtlCase decNwTtlCase = new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build();\r
+ Action actionDecNW = new ActionBuilder().setOrder(actionList.size()).setAction(decNwTtlCase).build();\r
+ actionList.add(actionDecNW);\r
+\r
+ ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetSource(new EthernetSourceBuilder().setAddress(macAddress).build());\r
+ ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ SetField setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ WriteMetadata writeMetadata = new WriteMetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId))).setMetadataMask(new BigInteger(DEFAULT_METADATA_MASK, 16)).build();\r
+ WriteMetadataCase writeMetadataCase = new WriteMetadataCaseBuilder().setWriteMetadata(writeMetadata).build();\r
+ Instruction instructionMeta = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(writeMetadataCase).build();\r
+ instructionList.add(instructionMeta);\r
+\r
+ GoToTable gotoTable = new GoToTableBuilder().setTableId(ARP_TABLE_ID).build();\r
+ GoToTableCase gotoTableCase = new GoToTableCaseBuilder().setGoToTable(gotoTable).build();\r
+ Instruction instructionGoto = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(gotoTableCase).build();\r
+ instructionList.add(instructionGoto);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(IP_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalNodeId);\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param virtualArp TODO\r
+ * @param physicalPath TODO\r
+ */\r
+ private void configArpTableEntry(UserId userId, VirtualArp virtualArp, PhysicalPath physicalPath) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ PhysicalLink physicalLink = physicalNetworkHelper.getFirstPhysicalLinkOfPhysicalPath(physicalPath);\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long)ETH_TYPE_IP)).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder().setIpv4Destination(convertIpAddressToIpPrefix(virtualArp.getIpAddress()).getIpv4Prefix());\r
+ Ipv4Match ipv4Match = ipv4MatchBuilder.build();\r
+\r
+ MetadataBuilder metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ Metadata metadata = metadataBuilder.build();\r
+\r
+ Match match = new MatchBuilder().setEthernetMatch(ethernetMatch).setLayer3Match(ipv4Match).setMetadata(metadata).build();\r
+\r
+ PushMplsAction pushMplsAction = new PushMplsActionBuilder().setEthernetType(ETH_TYPE_MPLS).build();\r
+ PushMplsActionCase pushMplsActionCase = new PushMplsActionCaseBuilder().setPushMplsAction(pushMplsAction).build();\r
+ Action actionPushMPLS = new ActionBuilder().setOrder(actionList.size()).setAction(pushMplsActionCase).build();\r
+ actionList.add(actionPushMPLS);\r
+\r
+ SetField setField = new SetFieldBuilder().setProtocolMatchFields(new ProtocolMatchFieldsBuilder().setMplsLabel((long)mplsLabelsOfPhysicalPaths.get(physicalPath.getPathId()).get(0)).build()).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetDestination(new EthernetDestinationBuilder().setAddress(virtualArp.getMacAddress()).build());\r
+ ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(physicalLink.getSrcPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(ARP_TABLE_ID).setPriority(DEFAULT_FLOW_PRIORITY);\r
+ Flow flow = flowBuilder.setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalLink.getSrcNodeId());\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param nemoFlow TODO\r
+ * @param physicalNodeId TODO\r
+ * @param inPhysicalPort TODO\r
+ * @param outPhysicalPort TODO\r
+ * @param policyPriority TODO\r
+ * @param layer3Forwarding TODO\r
+ */\r
+ private void configIpTableEntryForOperation(UserId userId,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow nemoFlow,\r
+ PhysicalNodeId physicalNodeId,\r
+ PhysicalPort inPhysicalPort,\r
+ PhysicalPort outPhysicalPort,\r
+ short policyPriority,\r
+ boolean layer3Forwarding) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ Match match = createMatch(userId, nemoFlow, inPhysicalPort);\r
+\r
+ if ( layer3Forwarding )\r
+ {\r
+ DecNwTtl decNwTtl = new DecNwTtlBuilder().build();\r
+ DecNwTtlCase decNwTtlCase = new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build();\r
+ Action actionDecNW = new ActionBuilder().setOrder(actionList.size()).setAction(decNwTtlCase).build();\r
+ actionList.add(actionDecNW);\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetSource(new EthernetSourceBuilder().setAddress(outPhysicalPort.getMacAddress()).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ SetField setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+ }\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetDestination(new EthernetDestinationBuilder().setAddress(getMacAddressOfConnectedExternalDevice(physicalNodeId, outPhysicalPort.getPortId())).build());\r
+ EthernetMatch ethernetMatch = ethernetMatchBuilder.build();\r
+\r
+ SetField setField = new SetFieldBuilder().setEthernetMatch(ethernetMatch).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(outPhysicalPort.getPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(layer3Forwarding ? IP_TABLE_ID : MAC_TABLE_ID);\r
+ Flow flow = flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY + policyPriority).setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalNodeId);\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param nemoFlow TODO\r
+ * @param inPhysicalPort TODO\r
+ * @param outPhysicalPath TODO\r
+ * @param policyPriority TODO\r
+ * @param layer3Forwarding TODO\r
+ */\r
+ private void configIpTableEntryForOperation(UserId userId,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow nemoFlow,\r
+ PhysicalPort inPhysicalPort,\r
+ PhysicalPath outPhysicalPath,\r
+ short policyPriority,\r
+ boolean layer3Forwarding) {\r
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();\r
+ PhysicalLink physicalLink = physicalNetworkHelper.getFirstPhysicalLinkOfPhysicalPath(outPhysicalPath);\r
+ List<Instruction> instructionList = new LinkedList<Instruction>();\r
+ List<Action> actionList = new LinkedList<Action>();\r
+\r
+ Match match = createMatch(userId, nemoFlow, inPhysicalPort);\r
+\r
+ if ( layer3Forwarding )\r
+ {\r
+ DecNwTtl decNwTtl = new DecNwTtlBuilder().build();\r
+ DecNwTtlCase decNwTtlCase = new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build();\r
+ Action actionDecNW = new ActionBuilder().setOrder(actionList.size()).setAction(decNwTtlCase).build();\r
+ actionList.add(actionDecNW);\r
+ }\r
+\r
+ PushMplsAction pushMplsAction = new PushMplsActionBuilder().setEthernetType(ETH_TYPE_MPLS).build();\r
+ PushMplsActionCase pushMplsActionCase = new PushMplsActionCaseBuilder().setPushMplsAction(pushMplsAction).build();\r
+ Action actionPushMPLS = new ActionBuilder().setOrder(actionList.size()).setAction(pushMplsActionCase).build();\r
+ actionList.add(actionPushMPLS);\r
+\r
+ SetField setField = new SetFieldBuilder().setProtocolMatchFields(new ProtocolMatchFieldsBuilder().setMplsLabel((long)mplsLabelsOfPhysicalPaths.get(outPhysicalPath.getPathId()).get(0)).build()).build();\r
+ SetFieldCase setFieldCase = new SetFieldCaseBuilder().setSetField(setField).build();\r
+ Action actionSetField = new ActionBuilder().setOrder(actionList.size()).setAction(setFieldCase).build();\r
+ actionList.add(actionSetField);\r
+\r
+ OutputAction outputAction = new OutputActionBuilder().setOutputNodeConnector(createNodeConnectorId(physicalLink.getSrcPortId())).build();\r
+ OutputActionCase outputActionCase = new OutputActionCaseBuilder().setOutputAction(outputAction).build();\r
+ Action actionOutput = new ActionBuilder().setOrder(actionList.size()).setAction(outputActionCase).build();\r
+ actionList.add(actionOutput);\r
+\r
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();\r
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();\r
+ Instruction instructionApply = new InstructionBuilder().setOrder(instructionList.size()).setInstruction(applyActionsCase).build();\r
+ instructionList.add(instructionApply);\r
+\r
+ Instructions instructions = new InstructionsBuilder().setInstruction(instructionList).build();\r
+\r
+ FlowId flowId = new FlowId(UUID.randomUUID().toString());\r
+ FlowBuilder flowBuilder = baseFlowBuilder().setId(flowId).setTableId(layer3Forwarding ? IP_TABLE_ID : MAC_TABLE_ID);\r
+ Flow flow = flowBuilder.setPriority(DEFAULT_FLOW_PRIORITY + policyPriority).setMatch(match).setInstructions(instructions).build();\r
+\r
+ NodeId nodeId = createNodeId(physicalLink.getSrcNodeId());\r
+ InstanceIdentifier<Flow> flowInsId = generateFlowInsId(userId, nodeId, flow.getTableId(), flow.getId());\r
+\r
+ writeTransaction.put(LogicalDatastoreType.CONFIGURATION, flowInsId, flow, true);\r
+ writeTransaction.submit();\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param userId TODO\r
+ * @param nemoFlow TODO\r
+ * @param physicalPort TODO\r
+ * @return TODO\r
+ */\r
+ private Match createMatch(UserId userId,\r
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow nemoFlow,\r
+ PhysicalPort physicalPort) {\r
+ List<MatchItem> matchItems = nemoFlow.getMatchItem();\r
+ MatchItem srcIpMatchItem = getMatchItem(matchItems, new MatchItemName("src-ip"));\r
+ MatchItem dstIpMatchItem = getMatchItem(matchItems, new MatchItemName("dst-ip"));\r
+\r
+ EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder();\r
+ Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder();\r
+ MetadataBuilder metadataBuilder = null;\r
+ boolean containEthernetMatch = false;\r
+ boolean containIpv4Match = false;\r
+\r
+ if ( null != userId ) {\r
+ metadataBuilder = new MetadataBuilder().setMetadata(BigInteger.valueOf(metadatas.get(userId)));\r
+ }\r
+\r
+ if ( null != srcIpMatchItem || null != dstIpMatchItem ) {\r
+ ethernetMatchBuilder = ethernetMatchBuilder.setEthernetType(new EthernetTypeBuilder().setType(new EtherType((long)ETH_TYPE_IP)).build());\r
+ containEthernetMatch = true;\r
+ }\r
+\r
+ if ( null != srcIpMatchItem ) {\r
+ String matchItemValue = srcIpMatchItem.getMatchItemValue().getStringValue();\r
+ ipv4MatchBuilder = ipv4MatchBuilder.setIpv4Source(new Ipv4Prefix(matchItemValue));\r
+ containIpv4Match = true;\r
+ }\r
+\r
+ if ( null != dstIpMatchItem ) {\r
+ String matchItemValue = dstIpMatchItem.getMatchItemValue().getStringValue();\r
+ ipv4MatchBuilder = ipv4MatchBuilder.setIpv4Destination(new Ipv4Prefix(matchItemValue));\r
+ containIpv4Match = true;\r
+ }\r
+\r
+ MatchBuilder matchBuilder = new MatchBuilder();\r
+\r
+ if ( null != physicalPort ) {\r
+ matchBuilder = matchBuilder.setInPort(createNodeConnectorId(physicalPort.getPortId()));\r
+ }\r
+\r
+ if ( containEthernetMatch ) {\r
+ matchBuilder = matchBuilder.setEthernetMatch(ethernetMatchBuilder.build());\r
+ }\r
+\r
+ if ( null != userId ) {\r
+ matchBuilder = matchBuilder.setMetadata(metadataBuilder.build());\r
+ }\r
+\r
+ if ( containIpv4Match ) {\r
+ matchBuilder = matchBuilder.setLayer3Match(ipv4MatchBuilder.build());\r
+ }\r
+\r
+ return matchBuilder.build();\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @return TODO\r
+ */\r
+ private FlowBuilder baseFlowBuilder() {\r
+ return new FlowBuilder().setBarrier(false).setHardTimeout(0).setIdleTimeout(0);\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param physicalPortId TODO\r
+ * @return TODO\r
+ */\r
+ private NodeConnectorId createNodeConnectorId(PhysicalPortId physicalPortId) {\r
+ return new NodeConnectorId(physicalPortId.getValue());\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param nodeId TODO\r
+ * @param nodeConnectorId TODO\r
+ * @return TODO\r
+ */\r
+ private InstanceIdentifier<NodeConnector> createNodeConnectorPath(NodeId nodeId, NodeConnectorId nodeConnectorId) {\r
+ return createNodePath(nodeId).child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId));\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param physicalNodeId TODO\r
+ * @param physicalPortId TODO\r
+ * @return TODO\r
+ */\r
+ private NodeConnectorRef createNodeConnectorRef(PhysicalNodeId physicalNodeId, PhysicalPortId physicalPortId) {\r
+ return new NodeConnectorRef(createNodeConnectorPath(createNodeId(physicalNodeId), createNodeConnectorId(physicalPortId)));\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param physicalNodeId TODO\r
+ * @return TODO\r
+ */\r
+ private NodeId createNodeId(PhysicalNodeId physicalNodeId) {\r
+ return new NodeId(physicalNodeId.getValue());\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param nodeId TODO\r
+ * @return TODO\r
+ */\r
+ private InstanceIdentifier<Node> createNodePath(NodeId nodeId) {\r
+ return InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(nodeId)).build();\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param physicalNodeId TODO\r
+ * @return TODO\r
+ */\r
+ private NodeRef createNodeRef(PhysicalNodeId physicalNodeId) {\r
+ return new NodeRef(createNodePath(createNodeId(physicalNodeId)));\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param nodeId TODO\r
+ * @param tableId TODO\r
+ * @return TODO\r
+ */\r
+ private InstanceIdentifier<Table> createTablePath(NodeId nodeId, Short tableId) {\r
+ return createNodePath(nodeId).builder().augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).build();\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param nodeId TODO\r
+ * @param tableId TODO\r
+ * @param flowId TODO\r
+ * @return TODO\r
+ */\r
+ private InstanceIdentifier<Flow> createFlowPath(NodeId nodeId, Short tableId, FlowId flowId) {\r
+ return createTablePath(nodeId, tableId).child(Flow.class, new FlowKey(flowId));\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ * @param ipAddress TODO\r
+ * @return TODO\r
+ */\r
+ private IpPrefix convertIpAddressToIpPrefix(IpAddress ipAddress) {\r
+ return new IpPrefix(new Ipv4Prefix(ipAddress.getIpv4Address().getValue() + "/32"));\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class MplsLabelGenerator {\r
+ private int i = 0;\r
+\r
+ protected int generateMplsLabel() {\r
+ return ++i;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class MeterIdGenerator {\r
+ private long i = 0;\r
+\r
+ protected long generateMeterId() {\r
+ return ++i;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class PhysicalNetworkHelper {\r
+ private Map<PhysicalNodeId, PhysicalNode> physicalNodeMap;\r
+ private Map<PhysicalLinkId, PhysicalLink> physicalLinkMap;\r
+ private Map<PhysicalPathId, PhysicalPath> physicalPathMap;\r
+ private Map<PhysicalNodeId, Map<PhysicalPortId, PhysicalPort>> physicalPortMap;\r
+\r
+ public PhysicalNetworkHelper(PhysicalNetwork physicalNetwork) {\r
+ physicalNodeMap = new HashMap<PhysicalNodeId, PhysicalNode>();\r
+ physicalLinkMap = new HashMap<PhysicalLinkId, PhysicalLink>();\r
+ physicalPathMap = new HashMap<PhysicalPathId, PhysicalPath>();\r
+ physicalPortMap = new HashMap<PhysicalNodeId, Map<PhysicalPortId, PhysicalPort>>();\r
+\r
+ List<PhysicalNode> physicalNodes = physicalNetwork.getPhysicalNodes().getPhysicalNode();\r
+ Map<PhysicalPortId, PhysicalPort> physicalPorts;\r
+\r
+ for ( PhysicalNode physicalNode : physicalNodes ) {\r
+ physicalNodeMap.put(physicalNode.getNodeId(), physicalNode);\r
+\r
+ physicalPorts = new HashMap<PhysicalPortId, PhysicalPort>();\r
+ physicalPortMap.put(physicalNode.getNodeId(), physicalPorts);\r
+\r
+ for ( PhysicalPort physicalPort : physicalNode.getPhysicalPort() ) {\r
+ physicalPorts.put(physicalPort.getPortId(), physicalPort);\r
+ }\r
+ }\r
+\r
+ List<PhysicalLink> physicalLinks = physicalNetwork.getPhysicalLinks().getPhysicalLink();\r
+\r
+ for ( PhysicalLink physicalLink : physicalLinks ) {\r
+ physicalLinkMap.put(physicalLink.getLinkId(), physicalLink);\r
+ }\r
+\r
+ if ( null != physicalNetwork.getPhysicalPaths() ) {\r
+ List<PhysicalPath> physicalPaths = physicalNetwork.getPhysicalPaths().getPhysicalPath();\r
+\r
+ if ( null != physicalPaths ) {\r
+ for ( PhysicalPath physicalPath : physicalPaths ) {\r
+// physicalPathMap.put(physicalPath.getPathId(), physicalPath);\r
+ physicalPathMap.put(physicalPath.getPathId(),\r
+ sortPhysicalLinksOfPhysicalPath(physicalPath));\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ protected PhysicalLink getPhysicalLink(PhysicalLinkId physicalLinkId) {\r
+ return physicalLinkMap.get(physicalLinkId);\r
+ }\r
+\r
+ protected PhysicalPath getPhysicalPath(PhysicalPathId physicalPathId) {\r
+ return physicalPathMap.get(physicalPathId);\r
+ }\r
+\r
+ protected PhysicalPort getPhysicalPort(PhysicalNodeId physicalNodeId, PhysicalPortId physicalPortId) {\r
+ return physicalPortMap.get(physicalNodeId).get(physicalPortId);\r
+ }\r
+\r
+ protected PhysicalLink getFirstPhysicalLinkOfPhysicalPath(PhysicalPath physicalPath) {\r
+// for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink\r
+// physicalLink : physicalPath.getPhysicalLink() ) {\r
+// if ( 0 == physicalLink.getOrder() ) {\r
+// return physicalLinkMap.get(physicalLink.getLinkId());\r
+// }\r
+// }\r
+//\r
+// return null;\r
+\r
+ if ( physicalPath.getPhysicalLink().isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ PhysicalLinkId physicalLinkId = physicalPath.getPhysicalLink().get(0).getLinkId();\r
+\r
+ return physicalLinkMap.get(physicalLinkId);\r
+ }\r
+\r
+ protected PhysicalLink getLastPhysicalLinkOfPhysicalPath(PhysicalPath physicalPath) {\r
+// long order = physicalPath.getPhysicalLink().size() - 1;\r
+//\r
+// for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink\r
+// physicalLink : physicalPath.getPhysicalLink() ) {\r
+// if ( physicalLink.getOrder() == order ) {\r
+// return physicalLinkMap.get(physicalLink.getLinkId());\r
+// }\r
+// }\r
+//\r
+// return null;\r
+\r
+ if ( physicalPath.getPhysicalLink().isEmpty() ) {\r
+ return null;\r
+ }\r
+\r
+ PhysicalLinkId physicalLinkId = physicalPath.getPhysicalLink()\r
+ .get(physicalPath.getPhysicalLink().size() - 1).getLinkId();\r
+\r
+ return physicalLinkMap.get(physicalLinkId);\r
+ }\r
+\r
+ private PhysicalPath sortPhysicalLinksOfPhysicalPath(PhysicalPath physicalPath) {\r
+ if ( physicalPath.getPhysicalLink().isEmpty()\r
+ || 1 == physicalPath.getPhysicalLink().size() ) {\r
+ return physicalPath;\r
+ }\r
+\r
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink> sortedPhysicalLinks =\r
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>(physicalPath.getPhysicalLink().size());\r
+ sortedPhysicalLinks.addAll(physicalPath.getPhysicalLink());\r
+\r
+ for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink\r
+ physicalLink : physicalPath.getPhysicalLink() ) {\r
+ sortedPhysicalLinks.set(physicalLink.getOrder().intValue(), physicalLink);\r
+ }\r
+\r
+ PhysicalPath physicalPath1 = new PhysicalPathBuilder(physicalPath)\r
+ .setPhysicalLink(sortedPhysicalLinks)\r
+ .build();\r
+\r
+ return physicalPath1;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * TODO\r
+ *\r
+ * @author Zhigang Ji\r
+ */\r
+ private class VirtualNetworkHelper {\r
+ private Map<VirtualNodeId, VirtualNode> virtualNodeMap;\r
+ private Map<VirtualLinkId, VirtualLink> virtualLinkMap;\r
+ private Map<VirtualPathId, VirtualPath> virtualPathMap;\r
+ private Map<VirtualNodeId, VirtualNode> virtualRouterMap;\r
+ private Map<VirtualNodeId, Map<VirtualPortId, VirtualPort>> virtualPortMap;\r
+ private Map<VirtualNodeId, VirtualPort> layer2ExternalVirtualPortMap;\r
+ private Map<VirtualNodeId, VirtualPort> layer3ExternalVirtualPortMap;\r
+ private Map<VirtualNodeId, Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>>> virtualSwitchConnectedInternalVirtualPortMap;\r
+ private Map<VirtualNodeId, Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>>> virtualRouterConnectedInternalVirtualPortMap;\r
+ private Map<VirtualArpKey, VirtualArp> virtualArpMap;\r
+ private Map<MacAddress, VirtualArp> macAddressKeyVirtualArpMap;\r
+\r
+ public VirtualNetworkHelper(VirtualNetwork virtualNetwork) {\r
+ virtualNodeMap = new HashMap<VirtualNodeId, VirtualNode>();\r
+ virtualLinkMap = new HashMap<VirtualLinkId, VirtualLink>();\r
+ virtualPathMap = new HashMap<VirtualPathId, VirtualPath>();\r
+ virtualRouterMap = new HashMap<VirtualNodeId, VirtualNode>();\r
+ virtualPortMap = new HashMap<VirtualNodeId, Map<VirtualPortId, VirtualPort>>();\r
+ layer2ExternalVirtualPortMap = new HashMap<VirtualNodeId, VirtualPort>();\r
+ layer3ExternalVirtualPortMap = new HashMap<VirtualNodeId, VirtualPort>();\r
+ virtualSwitchConnectedInternalVirtualPortMap =\r
+ new HashMap<VirtualNodeId, Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>>>();\r
+ virtualRouterConnectedInternalVirtualPortMap =\r
+ new HashMap<VirtualNodeId, Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>>>();\r
+ virtualArpMap = new HashMap<VirtualArpKey, VirtualArp>();\r
+ macAddressKeyVirtualArpMap = new HashMap<MacAddress, VirtualArp>();\r
+\r
+ List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();\r
+ Map<VirtualPortId, VirtualPort> virtualPorts;\r
+\r
+ for ( VirtualNode virtualNode : virtualNodes ) {\r
+ virtualNodeMap.put(virtualNode.getNodeId(), virtualNode);\r
+\r
+ if ( VirtualNode.NodeType.Vrouter == virtualNode.getNodeType() ) {\r
+ virtualRouterMap.put(virtualNode.getNodeId(), virtualNode);\r
+ }\r
+\r
+ virtualPorts = new HashMap<VirtualPortId, VirtualPort>();\r
+ virtualPortMap.put(virtualNode.getNodeId(), virtualPorts);\r
+\r
+ for ( VirtualPort virtualPort : virtualNode.getVirtualPort() ) {\r
+ virtualPorts.put(virtualPort.getPortId(), virtualPort);\r
+\r
+ if ( VirtualPort.PortType.External == virtualPort.getPortType() ) {\r
+ if ( null == virtualPort.getExternalMacAddresses() ) {\r
+ layer3ExternalVirtualPortMap.put(virtualNode.getNodeId(), virtualPort);\r
+ } else {\r
+ layer2ExternalVirtualPortMap.put(virtualNode.getNodeId(), virtualPort);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> virtualSwitchConnectedInternalVirtualPorts;\r
+ Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> virtualRouterConnectedInternalVirtualPorts;\r
+ VirtualNode virtualNode;\r
+ VirtualPort virtualPort;\r
+\r
+ for ( VirtualLink virtualLink : virtualLinks ) {\r
+ virtualLinkMap.put(virtualLink.getLinkId(), virtualLink);\r
+\r
+ virtualNode = virtualNodeMap.get(virtualLink.getDestNodeId());\r
+ virtualPort = virtualPortMap.get(virtualLink.getSrcNodeId()).get(virtualLink.getSrcPortId());\r
+\r
+ if ( VirtualNode.NodeType.Vswitch == virtualNode.getNodeType() ) {\r
+ virtualSwitchConnectedInternalVirtualPorts =\r
+ virtualSwitchConnectedInternalVirtualPortMap.get(virtualLink.getSrcNodeId());\r
+\r
+ if ( null == virtualSwitchConnectedInternalVirtualPorts ) {\r
+ virtualSwitchConnectedInternalVirtualPorts =\r
+ new HashMap<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>>();\r
+ virtualSwitchConnectedInternalVirtualPortMap.put(\r
+ virtualLink.getSrcNodeId(), virtualSwitchConnectedInternalVirtualPorts);\r
+ }\r
+\r
+ virtualSwitchConnectedInternalVirtualPorts.put(virtualLink.getDestNodeId(),\r
+ new AbstractMap.SimpleEntry<VirtualPort, VirtualLink>(virtualPort, virtualLink));\r
+ } else if ( VirtualNode.NodeType.Vrouter == virtualNode.getNodeType() ) {\r
+ virtualRouterConnectedInternalVirtualPorts =\r
+ virtualRouterConnectedInternalVirtualPortMap.get(virtualLink.getSrcNodeId());\r
+\r
+ if ( null == virtualRouterConnectedInternalVirtualPorts ) {\r
+ virtualRouterConnectedInternalVirtualPorts =\r
+ new HashMap<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>>();\r
+ virtualRouterConnectedInternalVirtualPortMap.put(\r
+ virtualLink.getSrcNodeId(), virtualRouterConnectedInternalVirtualPorts);\r
+ }\r
+\r
+ virtualRouterConnectedInternalVirtualPorts.put(virtualLink.getDestNodeId(),\r
+ new AbstractMap.SimpleEntry<VirtualPort, VirtualLink>(virtualPort, virtualLink));\r
+ }\r
+ }\r
+\r
+ List<VirtualPath> virtualPaths = virtualNetwork.getVirtualPaths().getVirtualPath();\r
+\r
+ for ( VirtualPath virtualPath : virtualPaths ) {\r
+ virtualPathMap.put(virtualPath.getPathId(), virtualPath);\r
+ }\r
+\r
+ List<VirtualArp> virtualArps = virtualNetwork.getVirtualArps().getVirtualArp();\r
+\r
+ for ( VirtualArp virtualArp : virtualArps ) {\r
+ virtualArpMap.put(virtualArp.getKey(), virtualArp);\r
+ macAddressKeyVirtualArpMap.put(virtualArp.getMacAddress(), virtualArp);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ protected VirtualLink getVirtualLink(VirtualLinkId virtualLinkId) {\r
+ return virtualLinkMap.get(virtualLinkId);\r
+ }\r
+\r
+ protected VirtualPath getVirtualPath(VirtualPathId virtualPathId) {\r
+ return virtualPathMap.get(virtualPathId);\r
+ }\r
+\r
+ protected Map<VirtualNodeId, VirtualNode> getVirtualRouters() {\r
+ return virtualRouterMap;\r
+ }\r
+\r
+ protected VirtualPort getLayer2ExternalVirtualPort(VirtualNodeId virtualNodeId) {\r
+ return layer2ExternalVirtualPortMap.get(virtualNodeId);\r
+ }\r
+\r
+ protected VirtualPort getLayer3ExternalVirtualPort(VirtualNodeId virtualNodeId) {\r
+ return layer3ExternalVirtualPortMap.get(virtualNodeId);\r
+ }\r
+\r
+ protected Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> getConnectedVirtualSwitches(\r
+ VirtualNodeId virtualNodeId) {\r
+ return virtualSwitchConnectedInternalVirtualPortMap.get(virtualNodeId);\r
+ }\r
+\r
+ protected Map<VirtualNodeId, Map.Entry<VirtualPort, VirtualLink>> getConnectedVirtualRouters(\r
+ VirtualNodeId virtualNodeId) {\r
+ return virtualRouterConnectedInternalVirtualPortMap.get(virtualNodeId);\r
+ }\r
+\r
+ protected VirtualArp getVirtualArp(MacAddress macAddress) {\r
+ return macAddressKeyVirtualArpMap.get(macAddress);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.renderer.openflow;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
+public class OpenflowRenderer implements AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OpenflowRenderer.class);
+
+ private DataBroker dataBroker;
+ private final ResourceManager resourceManager;
+ private final FlowTableManager flowTableMng;
+
+ public OpenflowRenderer(DataBroker dataBroker) {
+ super();
+ this.dataBroker = dataBroker;
+ System.out.println();
+ System.out.println("Waiting for loading config file about 30s...");
+
+ LOG.info("New ResourceManager.");
+ resourceManager = new ResourceManager(dataBroker);
+
+ LOG.info("New FlowTableManager.");
+ flowTableMng = new FlowTableManager(dataBroker, resourceManager);
+
+ LOG.info("Initialized openflow renderer.");
+ }
+
+ // *************
+ // AutoCloseable
+ // *************
+
+ @Override
+ public void close() throws Exception {
+ if (flowTableMng != null) flowTableMng.close();
+ if (resourceManager != null) resourceManager.close();
+ }
+}
+
--- /dev/null
+/*\r * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r *\r * This program and the accompanying materials are made available under the\r * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r * and is available at http://www.eclipse.org/legal/epl-v10.html\r */\r\rpackage org.opendaylight.nemo.renderer.openflow;\r\rimport org.opendaylight.controller.md.sal.binding.api.DataBroker;\rimport org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\rimport org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\rimport org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\rimport org.slf4j.Logger;\rimport org.slf4j.LoggerFactory;\r\rimport com.google.common.util.concurrent.FutureCallback;\rimport com.google.common.util.concurrent.Futures;\r\rimport com.google.common.collect.HashBasedTable;\rimport com.google.common.collect.Table;\r\rimport java.util.*;\rimport java.util.concurrent.Executors;\rimport java.util.concurrent.ScheduledExecutorService;\rimport com.google.common.util.concurrent.CheckedFuture;\r\rimport org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\rimport org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r\r\rimport com.fasterxml.jackson.core.JsonProcessingException;\rimport com.fasterxml.jackson.databind.JsonNode;\rimport com.fasterxml.jackson.databind.ObjectMapper;\r\r\rimport java.io.BufferedReader;\rimport java.io.FileInputStream;\rimport java.io.IOException;\rimport java.io.InputStreamReader;\rimport java.lang.*;\r\rimport org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\rimport org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\rimport org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetworkBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNodeInstance;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalPortInstance;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.AttributeValue;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.AttributeValueBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNodeBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNodeKey;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLinkBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLinkKey;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPort;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPortBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPortKey;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.Attribute;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.AttributeBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.AttributeKey;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.AttributeName;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalNodeId;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalPortId;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalLinkId;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalHostId;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalHostName;\r\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHostBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHostKey;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHost;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.host.instance.IpAddresses;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.host.instance.IpAddressesBuilder;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalLinks;\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalHosts;\r\r\rimport org.opendaylight.nemo.renderer.openflow.entity.ResourceBean;\r\rpublic class ResourceManager implements AutoCloseable {\r \r private static final Logger LOG = LoggerFactory.getLogger(ResourceManager.class);\r\r public final static String PROPERTY_FILE_PATH = "etc/nemo/nemo-openflow-renderer-resource.json";\r\r final private DataBroker dataProvider;\r\r private ObjectMapper objectMapper = null;\r\r private Table<PhysicalNodeId, PhysicalPortId, MacAddress> externalNetworkMacTable;\r\r public ResourceManager(DataBroker dataProvider){\r \r this.dataProvider = dataProvider;\r\r this.objectMapper = new ObjectMapper();\r\r this.externalNetworkMacTable = HashBasedTable.create();\r\r String resourceInfo = ReadFile(PROPERTY_FILE_PATH);\r\r buildPhysicalNetworkFromConfig(resourceInfo);\r\r LOG.info("nemo:Initialized resource manager for Openflow renderer.");\r }\r\r public Table<PhysicalNodeId, PhysicalPortId, MacAddress> getExternalNetworkMacTable(){\r\r return this.externalNetworkMacTable;\r }\r\r private void buildPhysicalNetworkFromConfig(String resource) {\r try {\r\r PhysicalNetworkBuilder phyNetwrokBuilder= new PhysicalNetworkBuilder();\r PhysicalNodeBuilder phyNodeBuilder = new PhysicalNodeBuilder();\r\r JsonNode rootNode = objectMapper.readTree(resource);\r\r JsonNode pn = rootNode.path("physicalnetwork");\r\r JsonNode nodes = pn.path("node");\r JsonNode links = pn.path("link");\r JsonNode hosts = pn.path("host");\r\r\r LOG.debug("Import physical nodes into DataStore.");\r for(int i = 0; i< nodes.size(); i++){\r LOG.debug("build physical node execution body");\r\r //JsonNode node = nodeIt.next();\r JsonNode node = nodes.get(i);\r JsonNode ports = node.path("port");\r\r PhysicalNodeBuilder nodeBuilder = new PhysicalNodeBuilder();\r nodeBuilder.setNodeId(new PhysicalNodeId(node.get("node-id").asText()));\r PhysicalNodeKey key = new PhysicalNodeKey(nodeBuilder.getNodeId());\r nodeBuilder.setKey(key);\r\r String nodetype = node.get("node-type").asText();\r\r if((!(nodetype.equals("switch"))) && (!(nodetype.equals("router")))){\r\r continue;\r }\r if(nodetype.equals("switch"))\r {\r nodeBuilder.setNodeType(PhysicalNodeInstance.NodeType.Switch);\r\r }else if(nodetype.equals("router")){\r\r nodeBuilder.setNodeType(PhysicalNodeInstance.NodeType.Router);\r }\r\r List<PhysicalPort> phyPortList = new ArrayList<PhysicalPort>();\r\r //for (Iterator<JsonNode> portIt = ports.elements(); portIt.hasNext(); ) {\r for(int j =0; j < ports.size(); j++){\r\r LOG.debug("build physical port execution body");\r\r //JsonNode port = portIt.next();\r JsonNode port = ports.get(j);\r\r PhysicalPortBuilder phyPortbuilder = new PhysicalPortBuilder();\r\r phyPortbuilder.setPortId(new PhysicalPortId(port.get("port-id").asText()));\r\r if((port.get("port-type").asText()).equals("external")) {\r\r phyPortbuilder.setPortType(PhysicalPortInstance.PortType.External);\r }\r else {\r\r phyPortbuilder.setPortType(PhysicalPortInstance.PortType.Internal);\r }\r\r //add mac-address for each port\r LOG.info("nemo:j=" + j);\r MacAddress mac = new MacAddress(port.get("port-mac-address").asText());\r phyPortbuilder.setMacAddress(mac);\r\r\r phyPortbuilder.setBandwidth((long) (port.get("bandwidth").asInt()));\r\r JsonNode attrs = port.path("attribute");\r\r List<Attribute> AttrList = new ArrayList<Attribute>();\r\r for(int r = 0; r < attrs.size(); r++){\r LOG.debug("build physical port attribute execution body.");\r JsonNode portattr = attrs.get(r);\r AttributeBuilder attrbuilder = new AttributeBuilder();\r attrbuilder.setAttributeName(new AttributeName(portattr.path("name").asText()));\r AttributeValueBuilder avbd = new AttributeValueBuilder();\r avbd.setStringValue(portattr.path("value").asText());\r attrbuilder.setKey(new AttributeKey(attrbuilder.getAttributeName()));\r attrbuilder.setAttributeValue(avbd.build());\r Attribute attr_instance = attrbuilder.build();\r AttrList.add(attr_instance);\r }\r\r /*\r Iterator<String> keys = attrs.fieldNames();\r while(keys.hasNext()) {\r\r LOG.info("build physical port attribute execution body.");\r String fieldName = keys.next();\r\r\r attrbuilder.setAttributeName(new AttributeName(fieldName));\r AttributeValueBuilder avbd = new AttributeValueBuilder();\r avbd.setStringValue(attrs.path(fieldName).asText());\r attrbuilder.setKey(new AttributeKey(attrbuilder.getAttributeName()));\r attrbuilder.setAttributeValue(avbd.build());\r Attribute attr_instance = attrbuilder.build();\r AttrList.add(attr_instance);\r }\r */\r\r phyPortbuilder.setAttribute(AttrList);\r phyPortList.add(phyPortbuilder.build());\r }\r nodeBuilder.setPhysicalPort(phyPortList);\r\r /*node attribute list*/\r JsonNode node_attrs = node.path("attribute");\r List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>\r node_AttrList = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>();\r for(int t = 0; t < node_attrs.size(); t++){\r LOG.debug("build physical node attribute execution body.");\r JsonNode node_attr = node_attrs.get(t);\r org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.AttributeBuilder\r attrbuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.AttributeBuilder();\r attrbuilder.setAttributeName(new AttributeName(node_attr.path("name").asText()));\r AttributeValueBuilder avbd = new AttributeValueBuilder();\r avbd.setStringValue(node_attr.path("value").asText());\r attrbuilder.setKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.AttributeKey(attrbuilder.getAttributeName()));\r attrbuilder.setAttributeValue(avbd.build());\r org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute node_attr_instance = attrbuilder.build();\r node_AttrList.add(node_attr_instance);\r }\r nodeBuilder.setAttribute((List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>) node_AttrList);\r\r PhysicalNode phyNode = nodeBuilder.build();\r //phyNodeList.add(phyNode);\r\r LOG.debug("Ready to write node to data store.");\r try {\r WriteTransaction t = dataProvider.newWriteOnlyTransaction();\r InstanceIdentifier<PhysicalNode> phynode_iid = InstanceIdentifier\r .builder(PhysicalNetwork.class)\r .child(PhysicalNodes.class)\r .child(PhysicalNode.class, key)\r .build();\r t.put(LogicalDatastoreType.OPERATIONAL, phynode_iid, phyNode, true);\r\r CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r Futures.addCallback(f, new FutureCallback<Void>() {\r @Override\r public void onFailure(Throwable t) {\r System.out.println("write transaction onFailure.");\r LOG.error("Could not write PhysicalNode", t);\r }\r\r @Override\r public void onSuccess(Void result) {\r //System.out.println("write transaction onSuccess.");\r LOG.debug("write transaction onSuccess.");\r }\r });\r\r } catch (Exception e) {\r e.printStackTrace();\r }\r }\r\r LOG.debug("Import physical links into DataStore.");\r for(int m = 0; m< links.size(); m++){\r\r LOG.debug("build physical link execution body");\r JsonNode link = links.get(m);\r\r String strLeftNodeId = link.get("left-node-id").asText();\r String strRightNodeId = link.get("right-node-id").asText();\r\r if(strLeftNodeId.contains("external")||strRightNodeId.contains("external")){\r String strExternalNodeId = "";\r PhysicalNodeId accessNodeId = null;\r PhysicalPortId accessPortId = null;\r if(strLeftNodeId.contains("external")){\r strExternalNodeId = strLeftNodeId;\r accessNodeId = new PhysicalNodeId(link.get("right-node-id").asText());\r accessPortId = new PhysicalPortId(link.get("right-port-id").asText());\r }else{\r strExternalNodeId = strRightNodeId;\r accessNodeId = new PhysicalNodeId(link.get("left-node-id").asText());\r accessPortId = new PhysicalPortId(link.get("left-port-id").asText());\r }\r\r for(int b = 0; b < nodes.size(); b++){\r\r JsonNode pnode = nodes.get(b);\r if(strExternalNodeId.equals(pnode.get("node-id").asText())){\r\r MacAddress macAddress = new MacAddress(pnode.get("mac-address").asText());\r this.externalNetworkMacTable.put(accessNodeId, accessPortId, macAddress);\r break;\r }\r }\r\r continue;\r }\r\r PhysicalLinkBuilder linkBuilder = new PhysicalLinkBuilder();\r\r PhysicalLinkId phylinkid = new PhysicalLinkId(link.get("link-id").asText());\r linkBuilder.setLinkId(phylinkid);\r linkBuilder.setSrcNodeId(new PhysicalNodeId(link.get("left-node-id").asText()));\r linkBuilder.setSrcPortId(new PhysicalPortId(link.get("left-port-id").asText()));\r linkBuilder.setDestNodeId(new PhysicalNodeId(link.get("right-node-id").asText()));\r linkBuilder.setDestPortId(new PhysicalPortId(link.get("right-port-id").asText()));\r\r linkBuilder.setBandwidth((long) (link.get("link-bandwidth").asLong()));\r linkBuilder.setDelay((long) (link.get("delay").asLong()));\r linkBuilder.setMetric((long) (link.get("metric").asLong()));\r linkBuilder.setLossRate((short) (link.get("delay").asInt()));\r\r PhysicalLink phyLink = linkBuilder.build();\r\r LOG.debug("Ready to write link to data store.");\r try {\r WriteTransaction t = dataProvider.newWriteOnlyTransaction();\r InstanceIdentifier<PhysicalLink> phylink_iid = InstanceIdentifier\r .builder(PhysicalNetwork.class)\r .child(PhysicalLinks.class)\r .child(PhysicalLink.class, new PhysicalLinkKey(linkBuilder.getLinkId()))\r .build();\r t.put(LogicalDatastoreType.OPERATIONAL, phylink_iid, phyLink, true);\r\r CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r Futures.addCallback(f, new FutureCallback<Void>() {\r @Override\r public void onFailure(Throwable t) {\r System.out.println("write transaction onFailure.");\r LOG.error("Could not write PhysicalLink", t);\r }\r\r @Override\r public void onSuccess(Void result) {\r //System.out.println("write transaction onSuccess.");\r LOG.debug("write transaction onSuccess.");\r }\r });\r\r } catch (Exception e) {\r e.printStackTrace();\r }\r }\r\r LOG.debug("Import hosts into DataStore.");\r for(int n = 0; n< hosts.size(); n++){\r\r LOG.debug("build host execution body");\r JsonNode host = hosts.get(n);\r\r PhysicalHostBuilder hostBuilder = new PhysicalHostBuilder();\r hostBuilder.setHostId(new PhysicalHostId(host.get("id").asText()));\r hostBuilder.setKey(new PhysicalHostKey(hostBuilder.getHostId()));\r hostBuilder.setHostName(new PhysicalHostName(host.get("name").asText()));\r\r IpAddressesBuilder IpAddrBuilder = new IpAddressesBuilder();\r List<IpAddress> ipList = new ArrayList<IpAddress>();\r\r JsonNode ipaddrs = host.path("ip-addresses");\r for(int p = 0 ; p < ipaddrs.size(); p++){\r JsonNode ipaddr = ipaddrs.get(p);\r IpAddress ip = new IpAddress(new Ipv4Address(ipaddr.get("ip-address").asText()));\r ipList.add(ip);\r }\r\r IpAddrBuilder.setIpAddress(ipList);\r hostBuilder.setIpAddresses(IpAddrBuilder.build());\r MacAddress mac = new MacAddress(host.get("mac-address").asText());\r hostBuilder.setMacAddress(mac);\r hostBuilder.setNodeId(new PhysicalNodeId(host.get("node-id").asText()));\r hostBuilder.setPortId(new PhysicalPortId(host.get("connector-id").asText()));\r\r PhysicalHost phyHost = hostBuilder.build();\r LOG.debug("Ready to write host to data store.");\r try {\r WriteTransaction t = dataProvider.newWriteOnlyTransaction();\r InstanceIdentifier<PhysicalHost> phyhost_iid = InstanceIdentifier\r .builder(PhysicalNetwork.class)\r .child(PhysicalHosts.class)\r .child(PhysicalHost.class, new PhysicalHostKey(hostBuilder.getHostId()))\r .build();\r t.put(LogicalDatastoreType.OPERATIONAL, phyhost_iid, phyHost, true);\r\r CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();\r Futures.addCallback(f, new FutureCallback<Void>() {\r @Override\r public void onFailure(Throwable t) {\r System.out.println("write transaction onFailure.");\r LOG.error("Could not write PhysicalHost", t);\r }\r\r @Override\r public void onSuccess(Void result) {\r //System.out.println("write transaction onSuccess.");\r LOG.debug("write transaction onSuccess.");\r }\r });\r\r } catch (Exception e) {\r e.printStackTrace();\r }\r\r }\r\r\r } catch (JsonProcessingException e) {\r e.printStackTrace();\r } catch(IOException e){\r e.printStackTrace();\r }\r\r LOG.debug("buildPhysicalNetworkFromConfig end.");\r System.out.print("Loading physical network configuration has been completed.");\r }\r\r private String ReadFile(String Path){\r BufferedReader reader = null;\r String laststr = "";\r try{\r FileInputStream fileInputStream = new FileInputStream(Path);\r InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");\r reader = new BufferedReader(inputStreamReader);\r String tempString = null;\r while((tempString = reader.readLine()) != null){\r laststr += tempString;\r }\r reader.close();\r }catch(IOException e){\r e.printStackTrace();\r }finally{\r if(reader != null){\r try {\r reader.close();\r } catch (IOException e) {\r e.printStackTrace();\r }\r }\r }\r return laststr;\r }\r\r @Override\r public void close() throws Exception {\r\r }\r\r\r\r}\r
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.nemo.renderer.openflow.entity;\r
+\r
+import java.util.List;\r
+\r
+public class HostBean {\r
+\r
+ public String getHostName() {\r
+ return hostName;\r
+ }\r
+\r
+ public void setHostName(String hostName) {\r
+ this.hostName = hostName;\r
+ }\r
+\r
+ private String hostName;\r
+\r
+ public List<String> getIPAddressList() {\r
+ return this.IPAddressList;\r
+ }\r
+\r
+ public void setStringList(List<String> IPAddressList) {\r
+ this.IPAddressList = IPAddressList;\r
+ }\r
+\r
+ private List<String> IPAddressList;\r
+\r
+ public String getMacAddress() {\r
+ return macAddress;\r
+ }\r
+\r
+ public void setMacAddress(String macAddress) {\r
+ this.macAddress = macAddress;\r
+ }\r
+\r
+ private String macAddress;\r
+\r
+ public String getNodeID() {\r
+ return nodeID;\r
+ }\r
+\r
+ public void setNodeID(String nodeID) {\r
+ this.nodeID = nodeID;\r
+ }\r
+\r
+ private String nodeID;\r
+\r
+ public String getConnectorID() {\r
+ return connectorID;\r
+ }\r
+\r
+ public void setConnectorID(String connectorID) {\r
+ this.connectorID = connectorID;\r
+ }\r
+\r
+ private String connectorID;\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+ \r
+package org.opendaylight.nemo.renderer.openflow.entity;\r
+\r
+public class LinkBean {\r
+\r
+ private String linkID;\r
+ private String leftNodeID;\r
+ private String leftPortID;\r
+ private String rightPortID;\r
+ private String linkBandwidth;\r
+\r
+ public String getLinkID() {\r
+ return linkID;\r
+ }\r
+\r
+ public void setLinkID(String linkID) {\r
+ this.linkID = linkID;\r
+ }\r
+\r
+ public String getLeftNodeID() {\r
+ return leftNodeID;\r
+ }\r
+\r
+ public void setLeftNodeID(String leftNodeID) {\r
+ this.leftNodeID = leftNodeID;\r
+ }\r
+\r
+ public String getLeftPortID() {\r
+ return leftPortID;\r
+ }\r
+\r
+ public void setLeftPortID(String leftPortID) {\r
+ this.leftPortID = leftPortID;\r
+ }\r
+\r
+ public String getRightNodeID() {\r
+ return rightNodeID;\r
+ }\r
+\r
+ public void setRightNodeID(String rightNodeID) {\r
+ this.rightNodeID = rightNodeID;\r
+ }\r
+\r
+ private String rightNodeID;\r
+\r
+ public String getRightPortID() {\r
+ return rightPortID;\r
+ }\r
+\r
+ public void setRightPortID(String rightPortID) {\r
+ this.rightPortID = rightPortID;\r
+ }\r
+\r
+ public String getLinkBandwidth() {\r
+ return linkBandwidth;\r
+ }\r
+\r
+ public void setLinkBandwidth(String linkBandwidth) {\r
+ this.linkBandwidth = linkBandwidth;\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.renderer.openflow.entity;\r
+\r
+import org.opendaylight.nemo.renderer.openflow.entity.PortBean;\r
+import java.util.List;\r
+\r
+public class NodeBean {\r
+\r
+ private String nodeID;\r
+ private String nodeType;\r
+ private String nodeCapacity;\r
+ private List<PortBean> portList;\r
+\r
+ public String getNodeID() {\r
+ return nodeID;\r
+ }\r
+\r
+ public void setNodeID(String nodeID) {\r
+ this.nodeID = nodeID;\r
+ }\r
+\r
+ public String getNodeType() {\r
+ return nodeType;\r
+ }\r
+\r
+ public void setNodeType(String nodeType) {\r
+ this.nodeType = nodeType;\r
+ }\r
+\r
+ public String getNodeCapacity() {\r
+ return nodeCapacity;\r
+ }\r
+\r
+ public void setNodeCapacity(String nodeCapacity) {\r
+ this.nodeCapacity = nodeCapacity;\r
+ }\r
+\r
+ public List<PortBean> getPortList() {\r
+ return portList;\r
+ }\r
+\r
+ public void setPortList(List<PortBean> portList) {\r
+ this.portList = portList;\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.nemo.renderer.openflow.entity;\r
+\r
+public class PortBean {\r
+\r
+ private String portID;\r
+ private String portIPAddress;\r
+ private String mask;\r
+ private String location;\r
+ private String bandwidth;\r
+\r
+ public String getPortID() {\r
+ return portID;\r
+ }\r
+\r
+ public void setPortID(String portID) {\r
+ this.portID = portID;\r
+ }\r
+\r
+ public String getPortIPAddress() {\r
+ return portIPAddress;\r
+ }\r
+\r
+ public void setPortIPAddress(String portIPAddress) {\r
+ this.portIPAddress = portIPAddress;\r
+ }\r
+\r
+ public String getMask() {\r
+ return mask;\r
+ }\r
+\r
+ public void setMask(String mask) {\r
+ this.mask = mask;\r
+ }\r
+\r
+ public String getLocation() {\r
+ return location;\r
+ }\r
+\r
+ public void setLocation(String location) {\r
+ this.location = location;\r
+ }\r
+\r
+ public String getBandwidth() {\r
+ return bandwidth;\r
+ }\r
+\r
+ public void setBandwidth(String bandwidth) {\r
+ this.bandwidth = bandwidth;\r
+ }\r
+}\r
--- /dev/null
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.renderer.openflow.entity;
+import org.opendaylight.nemo.renderer.openflow.entity.NodeBean;
+import org.opendaylight.nemo.renderer.openflow.entity.LinkBean;
+import org.opendaylight.nemo.renderer.openflow.entity.HostBean;
+
+import java.util.List;
+
+public class ResourceBean {
+ public List<NodeBean> getNodelist() {
+ return nodelist;
+ }
+
+ public void setNodelist(List<NodeBean> nodelist) {
+ this.nodelist = nodelist;
+ }
+
+ private List<NodeBean> nodelist;
+
+ public List<LinkBean> getLinklist() {
+ return linklist;
+ }
+
+ public void setLinklist(List<LinkBean> linklist) {
+ this.linklist = linklist;
+ }
+
+ private List<LinkBean> linklist;
+
+ public List<HostBean> getHostlist() {
+ return hostlist;
+ }
+
+ public void setHostlist(List<HostBean> hostlist) {
+ this.hostlist = hostlist;
+ }
+
+ private List<HostBean> hostlist;
+
+ //getter ,setter
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.openflow.renderer.impl.rev151010;
+
+import org.opendaylight.nemo.renderer.openflow.OpenflowRenderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class OpenflowRendererModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.openflow.renderer.impl.rev151010.AbstractOpenflowRendererModule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OpenflowRenderer.class);
+
+ public OpenflowRendererModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public OpenflowRendererModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.openflow.renderer.impl.rev151010.OpenflowRendererModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ LOG.info("Openflow Renderer createInstance()");
+ final OpenflowRenderer renderer = new OpenflowRenderer(getDataBrokerDependency());
+
+ final class CloseResources implements AutoCloseable {
+ @Override
+ public void close() throws Exception {
+ if (renderer != null) {
+ renderer.close();
+ }
+ LOG.info("Openflow Renderer (instance {}) tear down.", this);
+ }
+ }
+ return new CloseResources();
+ }
+
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: openflow-renderer-impl yang module local name: openflow-renderer-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Tue Sep 22 12:00:29 CST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.openflow.renderer.impl.rev151010;
+public class OpenflowRendererModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.openflow.renderer.impl.rev151010.AbstractOpenflowRendererModuleFactory {
+
+}
--- /dev/null
+{\r
+ "physicalnetwork":{\r
+ "node": [\r
+ {\r
+ "node-id": "openflow:1",\r
+ "node-type": "switch",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:1:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:1:3",\r
+ "port-type":"internal",\r
+ "port-ip-address":"",\r
+ "port-mac-address":"00:00:00:00:01:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:3"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:2",\r
+ "node-type": "switch",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:2:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:bb:8b:cf",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:2:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:3"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:3",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:3:1",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:2",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:3"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:4",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:fb:d1:76",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:4"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:4",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:4:1",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:04:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:4:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:0a:09:0b",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4:2"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "external:internet-1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:internet-1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [],\r
+ "mac-address":"08:00:27:40:9c:10",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:enterprise-1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:enterprise-1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [],\r
+ "mac-address":"08:00:27:0d:ef:79",\r
+ "protocol":"static"\r
+ }\r
+ ],\r
+\r
+\r
+ "link": [\r
+ {\r
+ "link-id":"link_1",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:3",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_2",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_3",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:3",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_4",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:2",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_5",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:3",\r
+ "right-node-id":"openflow:4",\r
+ "right-port-id":"openflow:4:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_6",\r
+ "left-node-id":"openflow:4",\r
+ "left-port-id":"openflow:4:1",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_7",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:4",\r
+ "right-node-id":"external:internet-1",\r
+ "right-port-id":"",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_8",\r
+ "left-node-id":"external:internet-1",\r
+ "left-port-id":"",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:4",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_9",\r
+ "left-node-id":"openflow:4",\r
+ "left-port-id":"openflow:4:2",\r
+ "right-node-id":"external:enterprise-1",\r
+ "right-port-id":"",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_10",\r
+ "left-node-id":"external:enterprise-1",\r
+ "left-port-id":"",\r
+ "right-node-id":"openflow:4",\r
+ "right-port-id":"openflow:4:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ }\r
+ ],\r
+\r
+ "host":[\r
+ {\r
+ "name":"video-server1",\r
+ "id":"7b796915-adf4-4356-b5ca-de005ac410c1",\r
+ "ip-addresses":[\r
+ {"ip-address":"192.168.11.2"}\r
+ ],\r
+ "mac-address":"00:00:00:00:00:03",\r
+ "node-id":"openflow:1",\r
+ "connector-id":"openflow:1:1"\r
+ },\r
+ {\r
+ "name":"vm1",\r
+ "id":"1eaf9a67-a171-42a8-9282-71cf702f61dd",\r
+ "ip-addresses":[\r
+ {"ip-address":"192.168.12.2"}\r
+ ],\r
+ "mac-address":"00:00:00:00:00:01",\r
+ "node-id":"openflow:1",\r
+ "connector-id":"openflow:1:2"\r
+ },\r
+ {\r
+ "name":"vm2",\r
+ "id":"6c787caa-156a-49ed-8546-547bdccf283c",\r
+ "ip-addresses":[\r
+ {"ip-address":"192.168.12.3"}\r
+ ],\r
+ "mac-address":"00:00:00:00:00:02",\r
+ "node-id":"openflow:2",\r
+ "connector-id":"openflow:2:1"\r
+ },\r
+ {\r
+ "name":"video-server2",\r
+ "id":"22282cca-9a13-4d0c-a67e-a933ebb0b0ae",\r
+ "ip-addresses":[\r
+ {"ip-address":"192.168.12.4"}\r
+ ],\r
+ "mac-address":"08:00:27:a0:a9:b3",\r
+ "node-id":"openflow:2",\r
+ "connector-id":"openflow:2:2"\r
+ }\r
+ ]\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+{\r
+ "physicalnetwork":{\r
+ "node": [\r
+ {\r
+ "node-id": "openflow:1",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:1:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:1:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:3"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:2",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:2:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:2:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:3"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:3",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:3:1",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:2",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:3"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:4",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:04",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:4"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:4",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:4:1",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:04:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:4:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:04:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4:2"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "external:branch-1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:branch-1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [],\r
+ "mac-address":"08:00:27:6e:f2:07",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:headquarters-1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:headquarters-1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [],\r
+ "mac-address":"08:00:27:cb:43:ca",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:fw1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:fw1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":"1"\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "fw1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:65:4c:f6",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"fw1:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"08:00:27:65:4c:f6",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:fw2",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:fw2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":"1"\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "fw2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:00:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"fw2:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"00:00:00:00:00:01",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:cache1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:cache1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "cache1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:00:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"cache1:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"00:00:00:00:00:02",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:cache2",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:cache2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "cache2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:90:0f:a5",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"cache2:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"08:00:27:90:0f:a5",\r
+ "protocol":"static"\r
+ }\r
+ ],\r
+\r
+ "link": [\r
+ {\r
+ "link-id":"link_1",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:3",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_2",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_3",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:2",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_4",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:3",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_5",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:3",\r
+ "right-node-id":"openflow:4",\r
+ "right-port-id":"openflow:4:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_6",\r
+ "left-node-id":"openflow:4",\r
+ "left-port-id":"openflow:4:1",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_7",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:4",\r
+ "right-node-id":"external:branch-1",\r
+ "right-port-id":"",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_8",\r
+ "left-node-id":"external:branch-1",\r
+ "left-port-id":"",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:4",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_9",\r
+ "left-node-id":"openflow:4",\r
+ "left-port-id":"openflow:4:2",\r
+ "right-node-id":"external:headquarters-1",\r
+ "right-port-id":"",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_10",\r
+ "left-node-id":"external:headquarters-1",\r
+ "left-port-id":"",\r
+ "right-node-id":"openflow:4",\r
+ "right-port-id":"openflow:4:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_11",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:1",\r
+ "right-node-id":"external:fw1",\r
+ "right-port-id":"fw1:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_12",\r
+ "left-node-id":"external:fw1",\r
+ "left-port-id":"fw1:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_13",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:2",\r
+ "right-node-id":"external:fw2",\r
+ "right-port-id":"fw2:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_14",\r
+ "left-node-id":"external:fw2",\r
+ "left-port-id":"fw2:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_15",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:1",\r
+ "right-node-id":"external:cache1",\r
+ "right-port-id":"cache1:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_16",\r
+ "left-node-id":"external:cache1",\r
+ "left-port-id":"cache1:1",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_17",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:2",\r
+ "right-node-id":"external:cache2",\r
+ "right-port-id":"cache2:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_18",\r
+ "left-node-id":"external:cache2",\r
+ "left-port-id":"cache2:1",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ }\r
+ ],\r
+\r
+ "host":[]\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+{\r
+ "physicalnetwork":{\r
+ "node": [\r
+ {\r
+ "node-id": "openflow:1",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:1:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:1:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:01:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:1:3"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:2",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:2:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:2:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:02:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:2:3"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:3",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:3:1",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:2",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:2"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:3",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:03",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:3"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:3:4",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:03:04",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:3:4"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "openflow:4",\r
+ "node-type": "router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "openflow:4:1",\r
+ "port-type":"internal",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:04:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4:1"\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "port-id": "openflow:4:2",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:04:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"openflow:4:2"\r
+ }\r
+ ]\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "node-id": "external:branch-1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:branch-1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [],\r
+ "mac-address":"08:00:27:6e:f2:07",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:headquarters-1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:headquarters-1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [],\r
+ "mac-address":"08:00:27:cb:43:ca",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:fw1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:fw1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":"1"\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "fw1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:65:4c:f6",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"fw1:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"08:00:27:65:4c:f6",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:fw2",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:fw2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":"1"\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "fw2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:00:01",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"fw2:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"00:00:00:00:00:01",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:cache1",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:cache1"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "cache1:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"00:00:00:00:00:02",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"cache1:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"00:00:00:00:00:02",\r
+ "protocol":"static"\r
+ },\r
+ {\r
+ "node-id": "external:cache2",\r
+ "node-type": "ext-router",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"external:cache2"\r
+ },\r
+ {\r
+ "name":"capacity",\r
+ "value":""\r
+ }\r
+ ],\r
+ "port": [\r
+ {\r
+ "port-id": "cache2:1",\r
+ "port-type":"external",\r
+ "port-ip-address": "",\r
+ "port-mac-address":"08:00:27:90:0f:a5",\r
+ "mask": "",\r
+ "bandwidth":"",\r
+ "attribute":[\r
+ {\r
+ "name":"location",\r
+ "value":"cache2:1"\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "mac-address":"08:00:27:90:0f:a5",\r
+ "protocol":"static"\r
+ }\r
+ ],\r
+\r
+ "link": [\r
+ {\r
+ "link-id":"link_1",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:3",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_2",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_3",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:2",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_4",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:3",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_5",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:3",\r
+ "right-node-id":"openflow:4",\r
+ "right-port-id":"openflow:4:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_6",\r
+ "left-node-id":"openflow:4",\r
+ "left-port-id":"openflow:4:1",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:3",\r
+ "link-bandwidth":"10240",\r
+ "metric":"1",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_7",\r
+ "left-node-id":"openflow:3",\r
+ "left-port-id":"openflow:3:4",\r
+ "right-node-id":"external:branch-1",\r
+ "right-port-id":"",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_8",\r
+ "left-node-id":"external:branch-1",\r
+ "left-port-id":"",\r
+ "right-node-id":"openflow:3",\r
+ "right-port-id":"openflow:3:4",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_9",\r
+ "left-node-id":"openflow:4",\r
+ "left-port-id":"openflow:4:2",\r
+ "right-node-id":"external:headquarters-1",\r
+ "right-port-id":"",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_10",\r
+ "left-node-id":"external:headquarters-1",\r
+ "left-port-id":"",\r
+ "right-node-id":"openflow:4",\r
+ "right-port-id":"openflow:4:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_11",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:1",\r
+ "right-node-id":"external:fw1",\r
+ "right-port-id":"fw1:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_12",\r
+ "left-node-id":"external:fw1",\r
+ "left-port-id":"fw1:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_13",\r
+ "left-node-id":"openflow:1",\r
+ "left-port-id":"openflow:1:2",\r
+ "right-node-id":"external:fw2",\r
+ "right-port-id":"fw2:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_14",\r
+ "left-node-id":"external:fw2",\r
+ "left-port-id":"fw2:1",\r
+ "right-node-id":"openflow:1",\r
+ "right-port-id":"openflow:1:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_15",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:1",\r
+ "right-node-id":"external:cache1",\r
+ "right-port-id":"cache1:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_16",\r
+ "left-node-id":"external:cache1",\r
+ "left-port-id":"cache1:1",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+\r
+ {\r
+ "link-id":"link_17",\r
+ "left-node-id":"openflow:2",\r
+ "left-port-id":"openflow:2:2",\r
+ "right-node-id":"external:cache2",\r
+ "right-port-id":"cache2:1",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ },\r
+ {\r
+ "link-id":"link_18",\r
+ "left-node-id":"external:cache2",\r
+ "left-port-id":"cache2:1",\r
+ "right-node-id":"openflow:2",\r
+ "right-port-id":"openflow:2:2",\r
+ "link-bandwidth":"10240",\r
+ "metric":"",\r
+ "delay":"",\r
+ "loss-rate":""\r
+ }\r
+ ],\r
+\r
+ "host":[]\r
+ }\r
+\r
+}
\ No newline at end of file
"This module contains the base YANG definitions for\r
NEMO Openflow renderer implementation.";\r
\r
- revision "2015-07-01" {\r
+ revision "2015-10-10" {\r
description\r
"Initial revision.";\r
}\r
--- /dev/null
+#!/bin/bash
+
+pkill -9 ofdatapath
+pkill -9 ofprotocol
+
+pkill -9 fail-ofdatapath
+pkill -9 fail-ofprotocol
+
+pkill -9 ext-ofdatapath
+pkill -9 ext-ofprotocol
+
+ip link del sw1-eth1
+ip link del sw1-eth2
+ip link del sw1-eth3
+ip link del sw2-eth1
+ip link del sw2-eth3
+ip link del sw3-eth1
+ip link del sw3-eth2
+ip link del sw3-eth3
+ip link del sw4-eth1
+
+ip link del server1-eth0
+ip netns delete server1
+ip link del vm1-eth0
+ip netns delete vm1
+ip link del vm2-eth0
+ip netns delete vm2
+
+rm /tmp/sw*
+rm /tmp/*.log
+rm /tmp/vconn-unix.*
+rm /tmp/vlogs.*
+
+exit 0
\ No newline at end of file
--- /dev/null
+#!/bin/bash
+
+pkill -9 ofdatapath
+pkill -9 ofprotocol
+
+pkill -9 fail-ofdatapath
+pkill -9 fail-ofprotocol
+
+pkill -9 ext-ofdatapath
+pkill -9 ext-ofprotocol
+
+ip link del sw1-eth1
+ip link del sw1-eth2
+ip link del sw1-eth3
+ip link del sw2-eth1
+ip link del sw2-eth3
+ip link del sw3-eth1
+ip link del sw3-eth2
+ip link del sw3-eth3
+ip link del sw4-eth1
+
+ip link del fw1-eth0
+ip netns delete fw1
+ip link del fw2-eth0
+ip netns delete fw2
+ip link del cache1-eth0
+ip netns delete cache1
+
+rm /tmp/sw*
+rm /tmp/*.log
+rm /tmp/vconn-unix.*
+rm /tmp/vlogs.*
+
+exit 0
\ No newline at end of file
--- /dev/null
+#!/bin/bash
+
+########## sw1 ##########
+ip link add name sw1-eth1 type veth peer name server1-eth0
+ip link add name sw1-eth2 type veth peer name vm1-eth0
+ip link add name sw1-eth3 type veth peer name sw3-eth1
+
+########## sw2 ##########
+ip link add name sw2-eth1 type veth peer name vm2-eth0
+ip link add name sw2-eth3 type veth peer name sw3-eth2
+
+########## sw3 ##########
+#ip link add name sw3-eth1 type veth peer name sw1-eth3
+#ip link add name sw3-eth2 type veth peer name sw2-eth3
+ip link add name sw3-eth3 type veth peer name sw4-eth1
+
+########## sw4 ##########
+#ip link add name sw4-eth1 type veth peer name sw3-eth3
+
+########## server1 ##########
+ip netns add server1
+ip link set server1-eth0 netns server1
+
+########## vm1 ##########
+ip netns add vm1
+ip link set vm1-eth0 netns vm1
+
+########## vm2 ##########
+ip netns add vm2
+ip link set vm2-eth0 netns vm2
+
+########## sw1 ##########
+ofdatapath -i sw1-eth1,sw1-eth2,sw1-eth3 punix:/tmp/sw1 -d 000000000001 1> /tmp/sw1-ofd.log 2> /tmp/sw1-ofd.log &
+ofprotocol unix:/tmp/sw1 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6661 1> /tmp/sw1-ofp.log 2> /tmp/sw1-ofp.log &
+
+########## sw2 ##########
+ofdatapath -i sw2-eth1,eth1,sw2-eth3 punix:/tmp/sw2 -d 000000000002 1> /tmp/sw2-ofd.log 2> /tmp/sw2-ofd.log &
+ofprotocol unix:/tmp/sw2 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6662 1> /tmp/sw2-ofp.log 2> /tmp/sw2-ofp.log &
+
+########## sw3 ##########
+ofdatapath -i sw3-eth1,sw3-eth2,sw3-eth3,eth2 punix:/tmp/sw3 -d 000000000003 1> /tmp/sw3-ofd.log 2> /tmp/sw3-ofd.log &
+ofprotocol unix:/tmp/sw3 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6663 1> /tmp/sw3-ofp.log 2> /tmp/sw3-ofp.log &
+
+########## sw4 ##########
+ofdatapath -i sw4-eth1,eth3 punix:/tmp/sw4 -d 000000000004 1> /tmp/sw4-ofd.log 2> /tmp/sw4-ofd.log &
+ofprotocol unix:/tmp/sw4 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6664 1> /tmp/sw4-ofp.log 2> /tmp/sw4-ofp.log &
+
+sleep 5
+
+########## lldp ##########
+dpctl unix:/tmp/sw1 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+dpctl unix:/tmp/sw2 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+dpctl unix:/tmp/sw3 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+dpctl unix:/tmp/sw4 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+
+exit 0
+
+
+
+ip netns exec server1 bash
+ifconfig server1-eth0 down
+ifconfig server1-eth0 hw ether 00:00:00:00:00:03
+ifconfig server1-eth0 192.168.11.2/24
+ifconfig server1-eth0 up
+ifconfig server1-eth0
+route add default gw 192.168.11.1
+route -n
+arp -s 192.168.11.1 00:00:0a:0b:0c:01
+exit
+
+ip netns exec vm1 bash
+ifconfig vm1-eth0 down
+ifconfig vm1-eth0 hw ether 00:00:00:00:00:01
+ifconfig vm1-eth0 192.168.12.2/24
+ifconfig vm1-eth0 up
+ifconfig vm1-eth0
+route add default gw 192.168.12.1
+route -n
+arp -s 192.168.12.1 00:00:0a:0b:0c:02
+arp -s 192.168.12.3 00:00:00:00:00:02
+arp -s 192.168.12.4 08:00:27:a0:a9:b3
+exit
+
+ip netns exec vm2 bash
+ifconfig vm2-eth0 down
+ifconfig vm2-eth0 hw ether 00:00:00:00:00:02
+ifconfig vm2-eth0 192.168.12.3/24
+ifconfig vm2-eth0 up
+ifconfig vm2-eth0
+route add default gw 192.168.12.1
+route -n
+arp -s 192.168.12.1 00:00:0a:0b:0c:02
+arp -s 192.168.12.2 00:00:00:00:00:01
+arp -s 192.168.12.4 08:00:27:a0:a9:b3
+exit
+
+
+
+ip netns exec server1 bash
+ping -c 3 192.168.12.4
+ping -c 3 192.168.13.2
+ping -c 3 172.168.1.2
+exit
+
+ip netns exec vm1 bash
+ping -c 3 192.168.12.3
+ping -c 3 192.168.12.4
+ping -c 3 192.168.11.2
+ping -c 3 192.168.13.2
+ping -c 3 172.168.1.2
+exit
+
+ip netns exec vm2 bash
+ping -c 3 192.168.12.2
+ping -c 3 192.168.12.4
+ping -c 3 192.168.11.2
+ping -c 3 192.168.13.2
+ping -c 3 172.168.1.2
+exit
--- /dev/null
+#!/bin/bash
+
+########## sw1 ##########
+ip link add name sw1-eth1 type veth peer name fw1-eth0
+ip link add name sw1-eth2 type veth peer name fw2-eth0
+ip link add name sw1-eth3 type veth peer name sw3-eth1
+
+########## sw2 ##########
+ip link add name sw2-eth1 type veth peer name cache1-eth0
+ip link add name sw2-eth3 type veth peer name sw3-eth2
+
+########## sw3 ##########
+#ip link add name sw3-eth1 type veth peer name sw1-eth3
+#ip link add name sw3-eth2 type veth peer name sw2-eth3
+ip link add name sw3-eth3 type veth peer name sw4-eth1
+
+########## sw4 ##########
+#ip link add name sw4-eth1 type veth peer name sw3-eth3
+
+########## fw1 ##########
+ip netns add fw1
+ip link set fw1-eth0 netns fw1
+
+########## fw2 ##########
+ip netns add fw2
+ip link set fw2-eth0 netns fw2
+
+########## cache1 ##########
+ip netns add cache1
+ip link set cache1-eth0 netns cache1
+
+########## sw1 ##########
+ofdatapath -i sw1-eth1,sw1-eth2,sw1-eth3 punix:/tmp/sw1 -d 000000000001 1> /tmp/sw1-ofd.log 2> /tmp/sw1-ofd.log &
+ofprotocol unix:/tmp/sw1 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6661 1> /tmp/sw1-ofp.log 2> /tmp/sw1-ofp.log &
+
+########## sw2 ##########
+ofdatapath -i sw2-eth1,eth1,sw2-eth3 punix:/tmp/sw2 -d 000000000002 1> /tmp/sw2-ofd.log 2> /tmp/sw2-ofd.log &
+ofprotocol unix:/tmp/sw2 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6662 1> /tmp/sw2-ofp.log 2> /tmp/sw2-ofp.log &
+
+########## sw3 ##########
+ofdatapath -i sw3-eth1,sw3-eth2,sw3-eth3,eth2 punix:/tmp/sw3 -d 000000000003 1> /tmp/sw3-ofd.log 2> /tmp/sw3-ofd.log &
+ofprotocol unix:/tmp/sw3 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6663 1> /tmp/sw3-ofp.log 2> /tmp/sw3-ofp.log &
+
+########## sw4 ##########
+ofdatapath -i sw4-eth1,eth3 punix:/tmp/sw4 -d 000000000004 1> /tmp/sw4-ofd.log 2> /tmp/sw4-ofd.log &
+ofprotocol unix:/tmp/sw4 tcp:127.0.0.1:6633 --fail=closed --listen=ptcp:6664 1> /tmp/sw4-ofp.log 2> /tmp/sw4-ofp.log &
+
+sleep 5
+
+########## lldp ##########
+dpctl unix:/tmp/sw1 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+dpctl unix:/tmp/sw2 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+dpctl unix:/tmp/sw3 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+dpctl unix:/tmp/sw4 flow-mod cmd=add,table=0 eth_type=0x88cc apply:output=ctrl:0xff
+
+exit 0
+
+
+
+ip netns exec fw2 bash
+ifconfig fw2-eth0 down
+ifconfig fw2-eth0 hw ether 00:00:00:00:00:01
+ifconfig fw2-eth0 up
+ifconfig fw2-eth0
+exit
+
+ip netns exec cache1 bash
+ifconfig cache1-eth0 down
+ifconfig cache1-eth0 hw ether 00:00:00:00:00:02
+ifconfig cache1-eth0 up
+ifconfig cache1-eth0
+exit
+
+
+
+echo 1 > /proc/sys/net/ipv4/ip_forward
+cat /proc/sys/net/ipv4/ip_forward
+
+iptables -A FORWARD -i eth0 -j DROP
+iptables -vxnL FORWARD
+
+iptables -D FORWARD -i eth0 -j DROP
+iptables -vxnL FORWARD
terms of the Eclipse Public License v1.0 which accompanies this distribution,
and is available at http://www.eclipse.org/legal/epl-v10.html
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</developerConnection>
- <tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/NEMO:Main</url>
+ <tag>HEAD</tag>
</scm>
-</project>
+</project>
\ No newline at end of file
terms of the Eclipse Public License v1.0 which accompanies this distribution,
and is available at http://www.eclipse.org/legal/epl-v10.html
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>releasepom</artifactId>
- <version>0.3.0-SNAPSHOT</version>
- <relativePath></relativePath>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <relativePath />
</parent>
<groupId>org.opendaylight.nemo</groupId>
<module>nemo-artifacts</module>
<module>nemo-api</module>
<module>nemo-impl</module>
+ <module>nemo-renderers</module>
<module>nemo-ui</module>
<module>nemo-features</module>
<module>nemo-karaf</module>
- <module>nemo-renderers</module>
</modules>
<url>https://wiki.opendaylight.org/view/NEMO:Main</url>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</developerConnection>
- <tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/NEMO:Main</url>
+ <tag>HEAD</tag>
</scm>
</project>