Adding nemo engine. 21/28921/1
authorA H <an.ho@huawei.com>
Thu, 29 Oct 2015 06:18:01 +0000 (23:18 -0700)
committerA H <an.ho@huawei.com>
Thu, 29 Oct 2015 06:18:01 +0000 (23:18 -0700)
Change-Id: I5f959c18bfaa11ff1db7f1b34b3840e836ed7cf5
Signed-off-by: A H <an.ho@huawei.com>
98 files changed:
diff.log [new file with mode: 0644]
nemo-api/src/main/yang/nemo-common.yang
nemo-api/src/main/yang/nemo-intent.yang
nemo-api/src/main/yang/nemo-object.yang
nemo-api/src/main/yang/nemo-operation.yang
nemo-api/src/main/yang/nemo-result.yang
nemo-api/src/main/yang/nemo-user.yang [new file with mode: 0644]
nemo-features/pom.xml
nemo-features/src/main/features/features.xml
nemo-impl/pom.xml
nemo-impl/src/main/java/README [deleted file]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/ConnectionMapper.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/FlowManager.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolutionException.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolver.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolverUtils.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/NodeMapper.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/OperationResolver.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/Edge.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/RoutingAlgorithm.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/Vertex.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/PNComputationUnit.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNComputationUnit.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingException.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingUnit.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingUnitUtils.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/UserManager.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/advancedquery/AdvancedQuery.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/advancedquery/QueryDefinitionCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/AAA.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/RegisterUser.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/TenantManage.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/transactionmanager/TransactionBegin.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/transactionmanager/TransactionEnd.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/VNSpaceManagement.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/ConnectionInstanceCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/FlowInstanceCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/NodeInstanceCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/OperationInstanceCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/ResultInstanceCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/languagestyle/LanguageIntent.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteConnection.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteFlow.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteIntent.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteNode.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteOperation.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteResult.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateConnection.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateFlow.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateIntent.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateNode.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateOperation.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateResult.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/ConnectionDefinitionCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/FlowDefinitionCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/NodeDefinitionCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/OperationDefinitionCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/ResultDefinitionCheck.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/engine/impl/rev151010/NemoEngineModule.java [new file with mode: 0644]
nemo-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/engine/impl/rev151010/NemoEngineModuleFactory.java [new file with mode: 0644]
nemo-impl/src/main/resources/etc/opendaylight/karaf/config.xml [new file with mode: 0644]
nemo-impl/src/main/resources/nemo-odl.py [new file with mode: 0644]
nemo-impl/src/main/yang/generic-physical-network.yang [new file with mode: 0644]
nemo-impl/src/main/yang/generic-virtual-network.yang [new file with mode: 0644]
nemo-impl/src/main/yang/intent-mapping-result.yang [new file with mode: 0644]
nemo-impl/src/main/yang/intent-processing-status.yang [new file with mode: 0644]
nemo-impl/src/main/yang/nemo-engine-common.yang [new file with mode: 0644]
nemo-impl/src/main/yang/nemo-engine-impl.yang [new file with mode: 0644]
nemo-impl/src/test/java/README [deleted file]
nemo-impl/src/test/resources/bod-1.py [new file with mode: 0644]
nemo-impl/src/test/resources/bod-2.py [new file with mode: 0644]
nemo-impl/src/test/resources/servicechain.py [new file with mode: 0644]
nemo-karaf/pom.xml
nemo-renderers/openflow-renderer/pom.xml
nemo-renderers/openflow-renderer/src/main/java/README [deleted file]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/FlowTableManager.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/FlowUtils.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/OpenflowRenderer.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/ResourceManager.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/HostBean.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/LinkBean.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/NodeBean.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/PortBean.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/ResourceBean.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/openflow/renderer/impl/rev151010/OpenflowRendererModule.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/openflow/renderer/impl/rev151010/OpenflowRendererModuleFactory.java [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource-bod.json [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource-servicechain.json [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource.json [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/main/yang/openflow-renderer-impl.yang
nemo-renderers/openflow-renderer/src/test/java/README [deleted file]
nemo-renderers/openflow-renderer/src/test/resources/network-down-bod.sh [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/test/resources/network-down-servicechain.sh [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/test/resources/network-up-bod.sh [new file with mode: 0644]
nemo-renderers/openflow-renderer/src/test/resources/network-up-servicechain.sh [new file with mode: 0644]
nemo-renderers/pom.xml
nemo-ui/src/main/resources/README [deleted file]
pom.xml

diff --git a/diff.log b/diff.log
new file mode 100644 (file)
index 0000000..0737906
--- /dev/null
+++ b/diff.log
@@ -0,0 +1,2794 @@
+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>
index cbccc32a9d3a5dd444206673c481277ae7c2aff6..072745f2c9dc1905b18acf5c43140c011fae7c56 100644 (file)
@@ -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
index 21760a039374dfd03e77279cfa952c64a84719e1..91876aa6bd793b9ebb298adaed33e5ac5712c669 100644 (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
index 30500fdbb71c0858d500ad98c68bb36118907d70..347406d8349229ac2f2b83b8a4dd05401a64dfad 100644 (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
-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
index 219b19203fccd9e0f37da21d115d338ac4128987..8b4083a6701db580592661c1cb34b9b461d78cb1 100644 (file)
@@ -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
  */\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
index b350c21b8eb2320e6ea497b8e27935c7f59057f9..6daf69b5f1c27bc7c1c9827ced20fdef6e0a9d15 100644 (file)
@@ -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-api/src/main/yang/nemo-user.yang b/nemo-api/src/main/yang/nemo-user.yang
new file mode 100644 (file)
index 0000000..a2d8928
--- /dev/null
@@ -0,0 +1,80 @@
+/*\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
index c678d52d728e73c007418d0c16c59e1587b1f022..e4db9edfa58223eecd77cc1b622f1ca356752a76 100644 (file)
@@ -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>
@@ -107,6 +124,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <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>
@@ -119,6 +143,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <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>
index 4cec8905e615c4da65160c4a60b8e03b2165d166..f14ab7c65663c05eb7fd72516108677e87aa5ec2 100644 (file)
@@ -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
index fdb81457a0f81c389ca40a9498c2a4c51ec41add..c66209c2f88df771d25a4cdd56f86124ae1f95d3 100644 (file)
@@ -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,14 +24,48 @@ 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>
@@ -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 (file)
index e69de29..0000000
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/ConnectionMapper.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/ConnectionMapper.java
new file mode 100644 (file)
index 0000000..6d94b16
--- /dev/null
@@ -0,0 +1,1403 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/FlowManager.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/FlowManager.java
new file mode 100644 (file)
index 0000000..cf9e6d2
--- /dev/null
@@ -0,0 +1,51 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolutionException.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolutionException.java
new file mode 100644 (file)
index 0000000..f23a782
--- /dev/null
@@ -0,0 +1,50 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolver.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolver.java
new file mode 100644 (file)
index 0000000..c923a4c
--- /dev/null
@@ -0,0 +1,410 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolverUtils.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/IntentResolverUtils.java
new file mode 100644 (file)
index 0000000..5b16ef6
--- /dev/null
@@ -0,0 +1,652 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/NodeMapper.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/NodeMapper.java
new file mode 100644 (file)
index 0000000..4eabfc8
--- /dev/null
@@ -0,0 +1,1028 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/OperationResolver.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/OperationResolver.java
new file mode 100644 (file)
index 0000000..1d52689
--- /dev/null
@@ -0,0 +1,473 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/Edge.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/Edge.java
new file mode 100644 (file)
index 0000000..900264a
--- /dev/null
@@ -0,0 +1,82 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/RoutingAlgorithm.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/RoutingAlgorithm.java
new file mode 100644 (file)
index 0000000..86a0299
--- /dev/null
@@ -0,0 +1,208 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/Vertex.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/algorithm/Vertex.java
new file mode 100644 (file)
index 0000000..af5b9a6
--- /dev/null
@@ -0,0 +1,42 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/PNComputationUnit.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/PNComputationUnit.java
new file mode 100644 (file)
index 0000000..371f8d8
--- /dev/null
@@ -0,0 +1,435 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNComputationUnit.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNComputationUnit.java
new file mode 100644 (file)
index 0000000..e340cf1
--- /dev/null
@@ -0,0 +1,469 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingException.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingException.java
new file mode 100644 (file)
index 0000000..e887ef1
--- /dev/null
@@ -0,0 +1,50 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingUnit.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingUnit.java
new file mode 100644 (file)
index 0000000..d4655bd
--- /dev/null
@@ -0,0 +1,1147 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingUnitUtils.java b/nemo-impl/src/main/java/org/opendaylight/nemo/intent/computation/VNMappingUnitUtils.java
new file mode 100644 (file)
index 0000000..39bcfae
--- /dev/null
@@ -0,0 +1,40 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/UserManager.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/UserManager.java
new file mode 100644 (file)
index 0000000..5e49698
--- /dev/null
@@ -0,0 +1,267 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/advancedquery/AdvancedQuery.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/advancedquery/AdvancedQuery.java
new file mode 100644 (file)
index 0000000..98bc16d
--- /dev/null
@@ -0,0 +1,521 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/advancedquery/QueryDefinitionCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/advancedquery/QueryDefinitionCheck.java
new file mode 100644 (file)
index 0000000..c47efbe
--- /dev/null
@@ -0,0 +1,162 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/AAA.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/AAA.java
new file mode 100644 (file)
index 0000000..a1a4753
--- /dev/null
@@ -0,0 +1,72 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/RegisterUser.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/RegisterUser.java
new file mode 100644 (file)
index 0000000..d598b02
--- /dev/null
@@ -0,0 +1,92 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/TenantManage.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/tenantmanager/TenantManage.java
new file mode 100644 (file)
index 0000000..c20756b
--- /dev/null
@@ -0,0 +1,174 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/transactionmanager/TransactionBegin.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/transactionmanager/TransactionBegin.java
new file mode 100644 (file)
index 0000000..b0f7eb2
--- /dev/null
@@ -0,0 +1,24 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/transactionmanager/TransactionEnd.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/transactionmanager/TransactionEnd.java
new file mode 100644 (file)
index 0000000..c4f2f7b
--- /dev/null
@@ -0,0 +1,23 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/VNSpaceManagement.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/VNSpaceManagement.java
new file mode 100644 (file)
index 0000000..9c02260
--- /dev/null
@@ -0,0 +1,32 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/ConnectionInstanceCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/ConnectionInstanceCheck.java
new file mode 100644 (file)
index 0000000..aec2430
--- /dev/null
@@ -0,0 +1,104 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/FlowInstanceCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/FlowInstanceCheck.java
new file mode 100644 (file)
index 0000000..6ba1352
--- /dev/null
@@ -0,0 +1,59 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/NodeInstanceCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/NodeInstanceCheck.java
new file mode 100644 (file)
index 0000000..e1f17f6
--- /dev/null
@@ -0,0 +1,65 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/OperationInstanceCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/OperationInstanceCheck.java
new file mode 100644 (file)
index 0000000..b7603db
--- /dev/null
@@ -0,0 +1,122 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/ResultInstanceCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/instancecheck/ResultInstanceCheck.java
new file mode 100644 (file)
index 0000000..62dac6f
--- /dev/null
@@ -0,0 +1,30 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/languagestyle/LanguageIntent.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/languagestyle/LanguageIntent.java
new file mode 100644 (file)
index 0000000..670d1b5
--- /dev/null
@@ -0,0 +1,42 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteConnection.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteConnection.java
new file mode 100644 (file)
index 0000000..9e8baf5
--- /dev/null
@@ -0,0 +1,116 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteFlow.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteFlow.java
new file mode 100644 (file)
index 0000000..6a45e31
--- /dev/null
@@ -0,0 +1,112 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteIntent.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteIntent.java
new file mode 100644 (file)
index 0000000..1eaba1b
--- /dev/null
@@ -0,0 +1,131 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteNode.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteNode.java
new file mode 100644 (file)
index 0000000..7088f4f
--- /dev/null
@@ -0,0 +1,114 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteOperation.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteOperation.java
new file mode 100644 (file)
index 0000000..81cb365
--- /dev/null
@@ -0,0 +1,114 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteResult.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/deleteintent/DeleteResult.java
new file mode 100644 (file)
index 0000000..8b73364
--- /dev/null
@@ -0,0 +1,22 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateConnection.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateConnection.java
new file mode 100644 (file)
index 0000000..607e83b
--- /dev/null
@@ -0,0 +1,101 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateFlow.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateFlow.java
new file mode 100644 (file)
index 0000000..5af2190
--- /dev/null
@@ -0,0 +1,99 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateIntent.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateIntent.java
new file mode 100644 (file)
index 0000000..1a34b9b
--- /dev/null
@@ -0,0 +1,130 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateNode.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateNode.java
new file mode 100644 (file)
index 0000000..1739b5f
--- /dev/null
@@ -0,0 +1,99 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateOperation.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateOperation.java
new file mode 100644 (file)
index 0000000..40b1e60
--- /dev/null
@@ -0,0 +1,102 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateResult.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/structurestyle/updateintent/UpdateResult.java
new file mode 100644 (file)
index 0000000..ede89b7
--- /dev/null
@@ -0,0 +1,54 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/ConnectionDefinitionCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/ConnectionDefinitionCheck.java
new file mode 100644 (file)
index 0000000..ff457b7
--- /dev/null
@@ -0,0 +1,199 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/FlowDefinitionCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/FlowDefinitionCheck.java
new file mode 100644 (file)
index 0000000..0926357
--- /dev/null
@@ -0,0 +1,126 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/NodeDefinitionCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/NodeDefinitionCheck.java
new file mode 100644 (file)
index 0000000..3f6a66f
--- /dev/null
@@ -0,0 +1,205 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/OperationDefinitionCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/OperationDefinitionCheck.java
new file mode 100644 (file)
index 0000000..9f4417e
--- /dev/null
@@ -0,0 +1,244 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/ResultDefinitionCheck.java b/nemo-impl/src/main/java/org/opendaylight/nemo/user/vnspacemanager/syntaxcheck/ResultDefinitionCheck.java
new file mode 100644 (file)
index 0000000..9249304
--- /dev/null
@@ -0,0 +1,21 @@
+/*\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
diff --git a/nemo-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/engine/impl/rev151010/NemoEngineModule.java b/nemo-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/engine/impl/rev151010/NemoEngineModule.java
new file mode 100644 (file)
index 0000000..2442f1c
--- /dev/null
@@ -0,0 +1,54 @@
+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();
+    }
+
+}
diff --git a/nemo-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/engine/impl/rev151010/NemoEngineModuleFactory.java b/nemo-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/engine/impl/rev151010/NemoEngineModuleFactory.java
new file mode 100644 (file)
index 0000000..225c3e1
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* 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 {
+
+}
diff --git a/nemo-impl/src/main/resources/etc/opendaylight/karaf/config.xml b/nemo-impl/src/main/resources/etc/opendaylight/karaf/config.xml
new file mode 100644 (file)
index 0000000..e73272c
--- /dev/null
@@ -0,0 +1,29 @@
+<?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
diff --git a/nemo-impl/src/main/resources/nemo-odl.py b/nemo-impl/src/main/resources/nemo-odl.py
new file mode 100644 (file)
index 0000000..2c32cbd
--- /dev/null
@@ -0,0 +1,384 @@
+#!/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)
diff --git a/nemo-impl/src/main/yang/generic-physical-network.yang b/nemo-impl/src/main/yang/generic-physical-network.yang
new file mode 100644 (file)
index 0000000..64d43ea
--- /dev/null
@@ -0,0 +1,443 @@
+/*\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
diff --git a/nemo-impl/src/main/yang/generic-virtual-network.yang b/nemo-impl/src/main/yang/generic-virtual-network.yang
new file mode 100644 (file)
index 0000000..cda628c
--- /dev/null
@@ -0,0 +1,414 @@
+/*\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
diff --git a/nemo-impl/src/main/yang/intent-mapping-result.yang b/nemo-impl/src/main/yang/intent-mapping-result.yang
new file mode 100644 (file)
index 0000000..d9fa4b7
--- /dev/null
@@ -0,0 +1,196 @@
+/*\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
diff --git a/nemo-impl/src/main/yang/intent-processing-status.yang b/nemo-impl/src/main/yang/intent-processing-status.yang
new file mode 100644 (file)
index 0000000..1110c5b
--- /dev/null
@@ -0,0 +1,164 @@
+/*\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
diff --git a/nemo-impl/src/main/yang/nemo-engine-common.yang b/nemo-impl/src/main/yang/nemo-engine-common.yang
new file mode 100644 (file)
index 0000000..a893845
--- /dev/null
@@ -0,0 +1,157 @@
+/*\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
diff --git a/nemo-impl/src/main/yang/nemo-engine-impl.yang b/nemo-impl/src/main/yang/nemo-engine-impl.yang
new file mode 100644 (file)
index 0000000..395c0f2
--- /dev/null
@@ -0,0 +1,54 @@
+/*\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
diff --git a/nemo-impl/src/test/java/README b/nemo-impl/src/test/java/README
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/nemo-impl/src/test/resources/bod-1.py b/nemo-impl/src/test/resources/bod-1.py
new file mode 100644 (file)
index 0000000..0536aab
--- /dev/null
@@ -0,0 +1,613 @@
+#!/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
diff --git a/nemo-impl/src/test/resources/bod-2.py b/nemo-impl/src/test/resources/bod-2.py
new file mode 100644 (file)
index 0000000..e480016
--- /dev/null
@@ -0,0 +1,613 @@
+#!/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
diff --git a/nemo-impl/src/test/resources/servicechain.py b/nemo-impl/src/test/resources/servicechain.py
new file mode 100644 (file)
index 0000000..b684b37
--- /dev/null
@@ -0,0 +1,524 @@
+#!/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)
+
+
index 7f23a3702c8731cb7b44eba78ef049e617aee89c..c5520cc830b68aa852c688787fe5244cb7960f36 100644 (file)
@@ -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>
@@ -60,14 +56,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <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>
index a88e190b4ed7f3860ae8ce1816951121b55c7398..ab0b3f56f8a1c954d4d2bc9711aacc64625cce06 100644 (file)
@@ -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>
@@ -37,6 +61,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <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>
@@ -46,6 +75,18 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <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>
@@ -63,6 +104,19 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       </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>
@@ -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 (file)
index e69de29..0000000
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/FlowTableManager.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/FlowTableManager.java
new file mode 100644 (file)
index 0000000..6ba4a0f
--- /dev/null
@@ -0,0 +1,273 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/FlowUtils.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/FlowUtils.java
new file mode 100644 (file)
index 0000000..e5d3254
--- /dev/null
@@ -0,0 +1,2579 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/OpenflowRenderer.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/OpenflowRenderer.java
new file mode 100644 (file)
index 0000000..3181776
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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();
+    }
+}
+
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/ResourceManager.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/ResourceManager.java
new file mode 100644 (file)
index 0000000..5101748
--- /dev/null
@@ -0,0 +1 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/HostBean.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/HostBean.java
new file mode 100644 (file)
index 0000000..66056fb
--- /dev/null
@@ -0,0 +1,65 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/LinkBean.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/LinkBean.java
new file mode 100644 (file)
index 0000000..20196a9
--- /dev/null
@@ -0,0 +1,69 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/NodeBean.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/NodeBean.java
new file mode 100644 (file)
index 0000000..c503726
--- /dev/null
@@ -0,0 +1,53 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/PortBean.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/PortBean.java
new file mode 100644 (file)
index 0000000..f369677
--- /dev/null
@@ -0,0 +1,57 @@
+/*\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
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/ResourceBean.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/nemo/renderer/openflow/entity/ResourceBean.java
new file mode 100644 (file)
index 0000000..d3085d9
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 
+}
+
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/openflow/renderer/impl/rev151010/OpenflowRendererModule.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/openflow/renderer/impl/rev151010/OpenflowRendererModule.java
new file mode 100644 (file)
index 0000000..13a67ac
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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();
+    }
+
+}
diff --git a/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/openflow/renderer/impl/rev151010/OpenflowRendererModuleFactory.java b/nemo-renderers/openflow-renderer/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/nemo/openflow/renderer/impl/rev151010/OpenflowRendererModuleFactory.java
new file mode 100644 (file)
index 0000000..7cc45a8
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* 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 {
+
+}
diff --git a/nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource-bod.json b/nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource-bod.json
new file mode 100644 (file)
index 0000000..8af843a
--- /dev/null
@@ -0,0 +1,435 @@
+{\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
diff --git a/nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource-servicechain.json b/nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource-servicechain.json
new file mode 100644 (file)
index 0000000..d7ca7a8
--- /dev/null
@@ -0,0 +1,612 @@
+{\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
diff --git a/nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource.json b/nemo-renderers/openflow-renderer/src/main/resources/etc/nemo/resource.json
new file mode 100644 (file)
index 0000000..d7ca7a8
--- /dev/null
@@ -0,0 +1,612 @@
+{\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
index dc8b4d999388a22ee16d2ad9fc90ba355f050eed..0a1637e66592011398fbd4869d9966e81c43ba87 100644 (file)
@@ -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 (file)
index e69de29..0000000
diff --git a/nemo-renderers/openflow-renderer/src/test/resources/network-down-bod.sh b/nemo-renderers/openflow-renderer/src/test/resources/network-down-bod.sh
new file mode 100644 (file)
index 0000000..23b64a1
--- /dev/null
@@ -0,0 +1,34 @@
+#!/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
diff --git a/nemo-renderers/openflow-renderer/src/test/resources/network-down-servicechain.sh b/nemo-renderers/openflow-renderer/src/test/resources/network-down-servicechain.sh
new file mode 100644 (file)
index 0000000..d610141
--- /dev/null
@@ -0,0 +1,34 @@
+#!/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
diff --git a/nemo-renderers/openflow-renderer/src/test/resources/network-up-bod.sh b/nemo-renderers/openflow-renderer/src/test/resources/network-up-bod.sh
new file mode 100644 (file)
index 0000000..0db75c6
--- /dev/null
@@ -0,0 +1,119 @@
+#!/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
diff --git a/nemo-renderers/openflow-renderer/src/test/resources/network-up-servicechain.sh b/nemo-renderers/openflow-renderer/src/test/resources/network-up-servicechain.sh
new file mode 100644 (file)
index 0000000..4b786c8
--- /dev/null
@@ -0,0 +1,83 @@
+#!/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
index 7066dda6e59e0ec5a9fa4411f607cd8863cc97d2..1024502239b6d9a1aa0d5e2247dc9e132159bcb4 100644 (file)
@@ -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 (file)
index e69de29..0000000
diff --git a/pom.xml b/pom.xml
index 22b85c9ddaaaebff8936988df60d3782d1b45ffa..d89815144d9a9079f0c758e9b3d0a295a84e03ef 100644 (file)
--- 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>