Merge "Add additional unit tests and asserts for NS Heal."
authorFu Jinhua <fu.jinhua@zte.com.cn>
Sat, 26 Aug 2017 02:22:25 +0000 (02:22 +0000)
committerGerrit Code Review <gerrit@onap.org>
Sat, 26 Aug 2017 02:22:25 +0000 (02:22 +0000)
24 files changed:
lcm/ns/ns_instant.py
lcm/ns/swagger.json [deleted file]
lcm/ns/urls.py
lcm/packages/tests/test_nf.py
lcm/packages/tests/test_sdc_nf.py
lcm/pub/config/config.py
lcm/pub/nfvi/vim/vimadaptor.py
lcm/pub/utils/toscaparser/__init__.py
lcm/pub/utils/toscaparser/basemodel.py
lcm/pub/utils/toscaparser/nsdmodel.py
lcm/pub/utils/toscaparser/vnfdmodel.py
lcm/settings.py
lcm/swagger/__init__.py [new file with mode: 0644]
lcm/swagger/tests.py [new file with mode: 0644]
lcm/swagger/urls.py [new file with mode: 0644]
lcm/swagger/vfc.db.swagger.json [new file with mode: 0644]
lcm/swagger/vfc.nslcm.swagger.json [new file with mode: 0644]
lcm/swagger/vfc.others.swagger.json [new file with mode: 0644]
lcm/swagger/vfc.sfclcm.swagger.json [new file with mode: 0644]
lcm/swagger/vfc.vllcm.swagger.json [new file with mode: 0644]
lcm/swagger/vfc.vnflcm.swagger.json [new file with mode: 0644]
lcm/swagger/views.py [new file with mode: 0644]
lcm/urls.py
lcm/workflows/build_in.py [new file with mode: 0644]

index 8f0f1c6..d16ea52 100644 (file)
@@ -21,15 +21,19 @@ import uuid
 from rest_framework import status
 
 from lcm.pub.database.models import DefPkgMappingModel, ServiceBaseInfoModel, InputParamMappingModel
-from lcm.pub.database.models import NSInstModel, NfPackageModel, VNFFGInstModel
-from lcm.pub.msapi.catalog import get_process_id, get_download_url_from_catalog
-from lcm.pub.msapi.catalog import query_rawdata_from_catalog, get_servicetemplate_id, get_servicetemplate
+from lcm.pub.database.models import NSInstModel, NfPackageModel, VNFFGInstModel, WFPlanModel, NSDModel
+from lcm.pub.msapi.catalog import get_process_id, query_rawdata_from_catalog
+from lcm.pub.msapi.catalog import get_servicetemplate_id, get_servicetemplate
 from lcm.pub.msapi.wso2bpel import workflow_run
 from lcm.pub.msapi.extsys import select_vnfm
 from lcm.pub.utils.jobutil import JobUtil
 from lcm.pub.utils import toscautil
 from lcm.pub.utils.values import ignore_case_get
 from lcm.pub.exceptions import NSLCMException
+from lcm.pub.config.config import WORKFLOW_OPTION
+from lcm.workflows import build_in
+from lcm.pub.msapi import activiti
+from lcm.pub.utils import toscaparser
 
 logger = logging.getLogger(__name__)
 
@@ -58,9 +62,15 @@ class InstantNSService(object):
                 location_constraints = self.req_data['locationConstraints']
             
             JobUtil.add_job_status(job_id, 5, 'Start query nsd(%s)' % ns_inst.nspackage_id)
-            src_plan = query_rawdata_from_catalog(ns_inst.nspackage_id, input_parameters)
-            dst_plan = toscautil.convert_nsd_model(src_plan["rawData"])
+            dst_plan = None
+            if WORKFLOW_OPTION == "wso2":
+                src_plan = query_rawdata_from_catalog(ns_inst.nspackage_id, input_parameters)
+                dst_plan = toscautil.convert_nsd_model(src_plan["rawData"])
+            else:
+                nsd_pkg = NSDModel.objects.get(id=ns_inst.nspackage_id)
+                dst_plan = toscaparser.parse_nsd(nsd_pkg.nsd_path, input_parameters)
             logger.debug('tosca plan dest:%s' % dst_plan)
+
             NSInstModel.objects.filter(id=self.ns_inst_id).update(nsd_model=dst_plan)
 
             params_json = json.JSONEncoder().encode(self.req_data["additionalParamForNs"])
@@ -109,11 +119,15 @@ class InstantNSService(object):
                                  creator='--',
                                  create_time=int(time.time()*1000)).save()
 
-            service_tpl = get_servicetemplate(ns_inst.nsd_id)
-            DefPkgMappingModel(service_id=self.ns_inst_id,
-                               service_def_id=service_tpl['csarId'],
-                               template_name=service_tpl['templateName'],
-                               template_id=service_tpl['serviceTemplateId']).save()
+            if WORKFLOW_OPTION == "wso2":
+                service_tpl = get_servicetemplate(ns_inst.nsd_id)
+                DefPkgMappingModel(service_id=self.ns_inst_id,
+                                   service_def_id=service_tpl['csarId'],
+                                   template_name=service_tpl['templateName'],
+                                   template_id=service_tpl['serviceTemplateId']).save()
+            else:
+                # TODO:
+                pass
 
             for key, val in self.req_data['additionalParamForNs'].items():
                 InputParamMappingModel(service_id=self.ns_inst_id,
@@ -125,24 +139,55 @@ class InstantNSService(object):
                     nsinstid=self.ns_inst_id,
                     endpointnumber=0).save()
 
-            servicetemplate_id = get_servicetemplate_id(ns_inst.nsd_id)
-            process_id = get_process_id('init', servicetemplate_id)
-            data = {"processId": process_id, "params": {"planInput": plan_input}}
-            logger.debug('ns-instant(%s) workflow data:%s' % (self.ns_inst_id, data))
-
-            ret = workflow_run(data)
-            logger.info("ns-instant(%s) workflow result:%s" % (self.ns_inst_id, ret))
-            JobUtil.add_job_status(job_id, 10, 'NS inst(%s) workflow started: %s' % (
-                self.ns_inst_id, ret.get('status')))
-            if ret.get('status') == 1:
-                return dict(data={'jobId': job_id}, status=status.HTTP_200_OK)
-            return dict(data={'error': ret['message']}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+            if WORKFLOW_OPTION == "wso2":
+                return self.start_wso2_workflow(job_id, ns_inst, plan_input)
+            elif WORKFLOW_OPTION == "activiti":
+                return self.start_activiti_workflow()
+            else:
+                return self.start_buildin_workflow(job_id, plan_input)
+
         except Exception as e:
             logger.error(traceback.format_exc())
             logger.error("ns-instant(%s) workflow error:%s" % (self.ns_inst_id, e.message))
             JobUtil.add_job_status(job_id, 255, 'NS instantiation failed: %s' % e.message)
             return dict(data={'error': e.message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
-            
+    
+    def start_wso2_workflow(self, job_id, ns_inst, plan_input):
+        servicetemplate_id = get_servicetemplate_id(ns_inst.nsd_id)
+        process_id = get_process_id('init', servicetemplate_id)
+        data = {"processId": process_id, "params": {"planInput": plan_input}}
+        logger.debug('ns-instant(%s) workflow data:%s' % (self.ns_inst_id, data))
+
+        ret = workflow_run(data)
+        logger.info("ns-instant(%s) workflow result:%s" % (self.ns_inst_id, ret))
+        JobUtil.add_job_status(job_id, 10, 'NS inst(%s) wso2 workflow started: %s' % (
+            self.ns_inst_id, ret.get('status')))
+        if ret.get('status') == 1:
+            return dict(data={'jobId': job_id}, status=status.HTTP_200_OK)
+        return dict(data={'error': ret['message']}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+    def start_activiti_workflow(self, job_id, plan_input):
+        plans = WFPlanModel.objects.filter()
+        if not plans:
+            raise NSLCMException("No plan is found, you should deploy plan first!")
+        data = {
+            "processId": plans[0].process_id, 
+            "params": plan_input 
+        }
+        ret = activiti.exec_workflow(data)
+        logger.info("ns-instant(%s) workflow result:%s" % (self.ns_inst_id, ret))
+        JobUtil.add_job_status(job_id, 10, 'NS inst(%s) activiti workflow started: %s' % (
+            self.ns_inst_id, ret.get('status')))
+        if ret.get('status') == 1:
+            return dict(data={'jobId': job_id}, status=status.HTTP_200_OK)
+        return dict(data={'error': ret['message']}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)      
+
+    def start_buildin_workflow(self, job_id, plan_input):
+        JobUtil.add_job_status(job_id, 10, 'NS inst(%s) buildin workflow started.' % 
+            self.ns_inst_id)
+        build_in.run_ns_instantiate(plan_input)
+        return dict(data={'jobId': job_id}, status=status.HTTP_200_OK)
+
     def get_vnf_vim_id(self, vim_id, location_constraints, vnfdid):
         for location in location_constraints:
             if "vnfProfileId" in location and vnfdid == location["vnfProfileId"]:
diff --git a/lcm/ns/swagger.json b/lcm/ns/swagger.json
deleted file mode 100644 (file)
index 6087a92..0000000
+++ /dev/null
@@ -1,1541 +0,0 @@
-{
-    "swagger": "2.0",
-    "info": {
-        "version": "1.0.0",
-        "title": "ONAP VFC Service Rest API"
-    },
-    "basePath": "/api/nslcm/v1",
-    "tags": [
-        {
-            "name": "vfc nslcm resource"
-        }
-    ],
-    "paths": {
-        "/nspackage": {
-            "get": {
-                "tags": [
-                    "ns package Resource"
-                ],
-                "summary": "query ns package info",
-                "description": "query ns package info",
-                "operationId": "query_ns_package",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/NsPackageListInfo"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            },
-            "post": {
-                "tags": [
-                    "ns package Resource"
-                ],
-                "summary": "ns package distribute",
-                "description": "ns package distribute",
-                "operationId": "ns_pkg_distribute",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "distribute request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/NsPkgPostRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/NsPkgPostResponse"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            }
-        },
-        "/nspackage/{csarId}": {
-            "get": {
-                "tags": [
-                    "ns package Resource"
-                ],
-                "summary": "query one ns package info",
-                "description": "query one ns package info",
-                "operationId": "query_one_ns_package",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "csarId",
-                        "in": "path",
-                        "description": "csar id of ns package",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/NsPackageInfo"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            },
-            "delete": {
-                "tags": [
-                    "ns package Resource"
-                ],
-                "summary": "delete ns pkg",
-                "description": "delete ns pkg",
-                "operationId": "delete_ns_pkg",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "csarId",
-                        "in": "path",
-                        "description": "csar id of ns package",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/NsPkgPostResponse"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            }
-        },
-        "/vnfpackage": {
-            "get": {
-                "tags": [
-                    "nf package Resource"
-                ],
-                "summary": "query nf package info",
-                "description": "query nf package info",
-                "operationId": "query_nf_package",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/NfPackageListInfo"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            },
-            "post": {
-                "tags": [
-                    "nf package Resource"
-                ],
-                "summary": "nf package distribute",
-                "description": "nf package distribute",
-                "operationId": "nf_pkg_distribute",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "distribute request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/NfPkgPostRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/NfPkgPostResponse"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            }
-        },
-        "/vnfpackage/{csarId}": {
-            "get": {
-                "tags": [
-                    "nf package Resource"
-                ],
-                "summary": "query one nf package info",
-                "description": "query one nf package info",
-                "operationId": "query_one_nf_package",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "csarId",
-                        "in": "path",
-                        "description": "csar id of nf package",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/NfPackageInfo"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            },
-            "delete": {
-                "tags": [
-                    "nf package Resource"
-                ],
-                "summary": "delete nf pkg",
-                "description": "delete nf pkg",
-                "operationId": "delete_nf_pkg",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "csarId",
-                        "in": "path",
-                        "description": "csar id of nf package",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/NfPkgPostResponse"
-                        }
-                    },
-                    "500": {
-                        "description": "internal error"
-                    }
-                }
-            }
-        },
-        "/ns/vls": {
-            "post": {
-                "tags": [
-                    "vls Resource"
-                ],
-                "summary": "vl create",
-                "description": "",
-                "operationId": "create_vl",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "instantiate request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/VlPostRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "201": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/VlPostResponse"
-                        }
-                    }
-                }
-            }
-        },
-        "/ns/vls/{vlId}": {
-            "get": {
-                "tags": [
-                    "vls Resource"
-                ],
-                "summary": "query the specified vl info",
-                "description": "",
-                "operationId": "query_vl",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "vlId",
-                        "in": "path",
-                        "description": "vl instance id",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/VlInfo"
-                        }
-                    },
-                    "404": {
-                        "description": "the vl instance id is wrong"
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            },
-            "delete": {
-                "tags": [
-                    "vls Resource"
-                ],
-                "summary": "delete vl",
-                "description": "",
-                "operationId": "delete_vl",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "",
-                        "name": "vlId",
-                        "in": "path"
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/DeleteVlResponse"
-                        }
-                    },
-                    "404": {
-                        "description": "the vl instance id is wrong"
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            }
-        },
-        "/ns/vnfs": {
-            "post": {
-                "tags": [
-                    "vnfs Resource"
-                ],
-                "summary": "vnf create",
-                "description": "",
-                "operationId": "create_vnf",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "instantiate request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/VnfPostRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "201": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/VnfPostResponse"
-                        }
-                    }
-                }
-            }
-        },
-        "/ns/vnfs/{vnfInstId}": {
-            "get": {
-                "tags": [
-                    "vnfs Resource"
-                ],
-                "summary": "query the specified vnf info",
-                "description": "",
-                "operationId": "query_vnf",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "vnfInstId",
-                        "in": "path",
-                        "description": "vnf instance id",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/VnfInfo"
-                        }
-                    },
-                    "404": {
-                        "description": "the vnf instance id is wrong"
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            },
-            "delete": {
-                "tags": [
-                    "vnfs Resource"
-                ],
-                "summary": "delete vnf",
-                "description": "",
-                "operationId": "delete_vnf",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "",
-                        "name": "vnfInstId",
-                        "in": "path"
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/DeleteResponse"
-                        }
-                    },
-                    "404": {
-                        "description": "the vl instance id is wrong"
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            }
-        },
-        "/ns/sfcs": {
-            "post": {
-                "tags": [
-                    "sfcs Resource"
-                ],
-                "summary": "sfc create",
-                "description": "",
-                "operationId": "create_sfc",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/SfcPostRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "201": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/SfcPostResponse"
-                        }
-                    }
-                }
-            }
-        },
-        "/ns/sfcs/{sfcInstId}": {
-            "get": {
-                "tags": [
-                    "sfcs Resource"
-                ],
-                "summary": "query the specified sfc info",
-                "description": "",
-                "operationId": "query_sfc",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "name": "sfcInstId",
-                        "in": "path",
-                        "description": "sfc instance id",
-                        "required": true,
-                        "type": "string"
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/SfcInfo"
-                        }
-                    },
-                    "404": {
-                        "description": "the sfc instance id is wrong"
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            },
-            "delete": {
-                "tags": [
-                    "vnfs Resource"
-                ],
-                "summary": "delete sfc",
-                "description": "",
-                "operationId": "delete_sfc",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "",
-                        "name": "sfcInstId",
-                        "in": "path"
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/DeleteResponse"
-                        }
-                    },
-                    "404": {
-                        "description": "the sfc instance id is wrong"
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            }
-        },
-        "/ns/{nsInstanceId}/postdeal": {
-            "post": {
-                "tags": [
-                    "ns postdeal"
-                ],
-                "summary": "ns postdeal",
-                "description": "",
-                "operationId": "ns_postdeal",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "",
-                        "name": "nsInstanceId",
-                        "in": "path"
-                    },
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/NSInstPostDetailRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": ""
-                    }
-                }
-            }
-        },
-        "/ns/{nsInstanceId}/scale": {
-            "post": {
-                "tags": [
-                    "ns scale"
-                ],
-                "summary": "ns scale",
-                "description": "ns scale",
-                "operationId": "ns_scale",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "",
-                        "name": "nsInstanceId",
-                        "in": "path"
-                    },
-                    {
-                        "in": "body",
-                        "name": "ScaleNSRequest",
-                        "description": "Scale NS Request Body",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/ScaleNsRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/NsScaleResponse"
-                        }
-                    },
-                    "201": {
-                        "description": "Invalid Request"
-                    }
-                }
-            }
-        },
-        "/ns/{ns_instance_id}": {
-            "delete": {
-                "tags": [
-                    "ns lcm"
-                ],
-                "summary": "ns delete",
-                "description": "ns delete",
-                "operationId": "ns_delete",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "Identifier of the NS instance.",
-                        "name": "ns_instance_id",
-                        "in": "path"
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "The NS instance resource and the associated NS identifier were deleted successfully."
-                    }
-                }
-            }
-        },
-        "/ns/{ns_instance_id}/terminate": {
-            "post": {
-                "tags": [
-                    "ns lcm"
-                ],
-                "summary": "ns terminate",
-                "description": "ns terminate",
-                "operationId": "ns_terminate",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "Identifier of the NS instance.",
-                        "name": "ns_instance_id",
-                        "in": "path"
-                    },
-                    {
-                        "in": "body",
-                        "name": "NsTerminateRequest",
-                        "description": "NsTerminateRequest",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/NsTerminateRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/NsTerminateResponse"
-                        }
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            }
-        },
-        "/ns/{ns_instance_id}/heal": {
-            "post": {
-                "tags": [
-                    "ns heal"
-                ],
-                "summary": "ns heal",
-                "description": "ns heal",
-                "operationId": "ns_heal",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "Identifier of the NS instance.",
-                        "name": "ns_instance_id",
-                        "in": "path"
-                    },
-                    {
-                        "in": "body",
-                        "name": "healVnfData",
-                        "description": "healVnfData",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/healVnfDataRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": "",
-                        "schema": {
-                            "$ref": "#/definitions/healVnfDataResponse"
-                        }
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            }
-        },
-        "/mandb/{modelName}": {
-            "get": {
-                "tags": [
-                    "ns lcm"
-                ],
-                "summary": "query ns table info",
-                "description": "query ns table info",
-                "operationId": "query_ns_table",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "model Name.",
-                        "name": "modelName",
-                        "in": "path"
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/TableInfo"
-                        }
-                    },
-                    "500": {
-                        "description": "the url is invalid"
-                    }
-                }
-            },
-            "delete": {
-                "tags": [
-                    "ns lcm"
-                ],
-                "summary": "ns table delete",
-                "description": "ns table delete",
-                "operationId": "ns_table_delete",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "model Name.",
-                        "name": "modelName",
-                        "in": "path"
-                    }
-                ],
-                "responses": {
-                    "204": {
-                        "description": "The tables were deleted successfully."
-                    }
-                }
-            }
-        },
-        "/ns": {
-            "get": {
-                "tags": [
-                    "ns lcm"
-                ],
-                "summary": "ns get",
-                "description": "ns get",
-                "operationId": "ns_get",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-  
-                ],
-                "responses": {
-                    "200": {
-                        "description": "successful operation",
-                        "schema": {
-                            "$ref": "#/definitions/NsInfo"
-                        }
-                    }
-                }
-            }
-        },
-        "/jobs/{jobId}":{
-          "post": {
-                "tags": [
-                    "jobstatus"
-                ],
-                "summary": "jobstatus",
-                "description": "",
-                "operationId": "jobstatus",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "parameters": [
-                    {
-                        "required": true,
-                        "type": "string",
-                        "description": "",
-                        "name": "jobId",
-                        "in": "path"
-                    },
-                    {
-                        "in": "body",
-                        "name": "body",
-                        "description": "request param",
-                        "required": true,
-                        "schema": {
-                            "$ref": "#/definitions/JobProgressRequest"
-                        }
-                    }
-                ],
-                "responses": {
-                    "202": {
-                        "description": ""
-                    }
-                }
-            }
-        }
-    },
-    "definitions": {
-        "NsPkgPostRequest": {
-            "type": "object",
-            "properties": {
-                "csarId": {
-                    "type": "string"
-                }
-            }
-        },
-        "NsPkgPostResponse": {
-            "type": "object",
-            "properties": {
-                "status": {
-                    "type": "string"
-                },
-                "statusDescription": {
-                    "type": "string"
-                },
-                "errorCode": {
-                    "type": "string"
-                }
-            }
-        },
-        "NsPackageListInfo": {
-            "type": "object",
-            "properties": {
-                "csars": {
-                    "$ref": "#/definitions/NsPkgListInfo"
-                }
-            }
-        },
-        "NsPkgListInfo": {
-            "type": "array",
-            "items": {
-                "type": "object"
-            }
-        },
-        "NsPackageInfo": {
-            "type": "object",
-            "properties": {
-                "csarId": {
-                    "type": "string"
-                },
-                "packageInfo": {
-                    "$ref": "#/definitions/NsPkgDetailInfo"
-                },
-                "nsInstanceInfo": {
-                    "$ref": "#/definitions/NsInstListInfo"
-                }
-            }
-        },
-        "NsPkgDetailInfo": {
-            "type": "object",
-            "properties": {
-                "nsdId": {
-                    "type": "string"
-                },
-                "nsdProvider": {
-                    "type": "string"
-                },
-                "nsdVersion": {
-                    "type": "string"
-                }
-            }
-        },
-        "NsInstListInfo": {
-            "type": "array",
-            "items": {
-                "type": "object"
-            }
-        },
-        "NfPkgPostRequest": {
-            "type": "object",
-            "properties": {
-                "csarId": {
-                    "type": "string"
-                }
-            }
-        },
-        "NfPkgPostResponse": {
-            "type": "object",
-            "properties": {
-                "jobId": {
-                    "type": "string"
-                }
-            }
-        },
-        "NfPackageListInfo": {
-            "type": "object",
-            "properties": {
-                "csars": {
-                    "$ref": "#/definitions/NfPkgListInfo"
-                }
-            }
-        },
-        "NfPkgListInfo": {
-            "type": "array",
-            "items": {
-                "type": "object"
-            }
-        },
-        "NfPackageInfo": {
-            "type": "object",
-            "properties": {
-                "csarId": {
-                    "type": "string"
-                },
-                "packageInfo": {
-                    "$ref": "#/definitions/NfPkgDetailInfo"
-                },
-                "imageInfo": {
-                    "$ref": "#/definitions/NfPkgImgInfo"
-                },
-                "vnfInstanceInfo": {
-                    "$ref": "#/definitions/NfInstListInfo"
-                }
-            }
-        },
-        "NfPkgDetailInfo": {
-            "type": "object",
-            "properties": {
-                "vnfdId": {
-                    "type": "string"
-                },
-                "vnfdProvider": {
-                    "type": "string"
-                },
-                "vnfdVersion": {
-                    "type": "string"
-                },
-                "vnfVersion": {
-                    "type": "string"
-                }
-            }
-        },
-        "NfInstListInfo": {
-            "type": "array",
-            "items": {
-                "type": "object"
-            }
-        },
-        "NfPkgImgInfo": {
-            "type": "array",
-            "items": {
-                "type": "object"
-            }
-        },
-        "VlPostRequest": {
-            "type": "object",
-            "properties": {
-                "jobId": {
-                    "type": "string"
-                },
-                "nsInstanceId": {
-                    "type": "string"
-                },
-                "flavourId": {
-                    "type": "string"
-                },
-                "sapData": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "pnfInfo": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "vnfInstanceData": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "nestedNsInstanceId": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "locationConstraints": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "additionalParamForNs": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "additionalParamForVnf": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "extNSVirtualLink": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "context": {
-                    "type": "string"
-                },
-                "vlIndex": {
-                    "type": "string"
-                }
-            }
-        },
-        "VlPostResponse": {
-            "type": "object",
-            "properties": {
-                "result": {
-                    "type": "integer",
-                    "enum": [
-                        0,
-                        1
-                    ]
-                },
-                "detail": {
-                    "type": "string"
-                },
-                "vlId": {
-                    "type": "string"
-                }
-            }
-        },
-        "VnfPostRequest": {
-            "type": "object",
-            "properties": {
-                "jobId": {
-                    "type": "string"
-                },
-                "nsInstanceId": {
-                    "type": "string"
-                },
-                "flavourId": {
-                    "type": "string"
-                },
-                "sapData": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "pnfInfo": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "vnfInstanceData": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "nestedNsInstanceId": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "locationConstraints": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "additionalParamForNs": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "additionalParamForVnf": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "extNSVirtualLink": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "context": {
-                    "type": "string"
-                },
-                "vnfIndex": {
-                    "type": "string"
-                }
-            }
-        },
-        "VnfPostResponse": {
-            "type": "object",
-            "properties": {
-                "vnfInstId": {
-                    "type": "string"
-                },
-                "jobId": {
-                    "type": "string"
-                }
-            }
-        },
-        "SfcPostRequest": {
-            "type": "object",
-            "properties": {
-                "jobId": {
-                    "type": "string"
-                },
-                "nsInstanceId": {
-                    "type": "string"
-                },
-                "sapData": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "vnfInstanceData": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "additionalParamForNs": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "additionalParamForVnf": {
-                    "type": "array",
-                    "items": {
-                        "type": "object"
-                    }
-                },
-                "sdnControllerId": {
-                    "type": "string"
-                },
-                "context": {
-                    "type": "string"
-                },
-                "fpindex": {
-                    "type": "string"
-                }
-            }
-        },
-        "NSInstPostDetailRequest": {
-            "type": "object",
-            "properties": {
-                "status": {
-                    "type": "string"
-                }
-            }
-        },
-        "JobProgressRequest": {
-            "type": "object",
-            "properties": {
-                "progress": {
-                    "type": "string"
-                },
-                "desc": {
-                    "type": "string"
-                },
-                "errcode": {
-                    "type": "string"
-                }
-            }
-        },
-        "SfcPostResponse": {
-            "type": "object",
-            "properties": {
-                "sfcInstId": {
-                    "type": "string"
-                },
-                "jobId": {
-                    "type": "string"
-                }
-            }
-        },
-        "VlInfo": {
-            "type": "object",
-            "properties": {
-                "vlId": {
-                    "type": "string"
-                },
-                "vlName": {
-                    "type": "string"
-                },
-                "vlStatus": {
-                    "type": "string"
-                }
-            }
-        },
-        "VnfInfo": {
-            "type": "object",
-            "properties": {
-                "vnfInstId": {
-                    "type": "string"
-                },
-                "vnfName": {
-                    "type": "string"
-                },
-                "vnfStatus": {
-                    "type": "string"
-                }
-            }
-        },
-        "SfcInfo": {
-            "type": "object",
-            "properties": {
-                "sfcInstId": {
-                    "type": "string"
-                },
-                "sfcName": {
-                    "type": "string"
-                },
-                "sfcStatus": {
-                    "type": "string"
-                }
-            }
-        },
-        "DeleteVlResponse": {
-            "type": "object",
-            "properties": {
-                "result": {
-                    "type": "integer",
-                    "enum": [
-                        0,
-                        1
-                    ]
-                },
-                "detail": {
-                    "type": "string"
-                }
-            }
-        },
-        "DeleteResponse": {
-            "type": "object",
-            "properties": {
-                "result": {
-                    "type": "integer",
-                    "enum": [
-                        0,
-                        1
-                    ]
-                },
-                "detail": {
-                    "type": "string"
-                }
-            }
-        },
-        "ScaleNsRequest": {
-            "type": "object",
-            "properties": {
-                "scaleType":{
-                    "type": "string"
-                },
-                "scaleNsByStepsData": {
-                    "$ref": "#/definitions/ScaleNsByStepsData"
-                }
-            }
-        },
-        "ScaleNsByStepsData": {
-            "type": "object",
-            "properties": {
-                "scalingDirection": {
-                    "type": "string"
-                },
-                "aspectId": {
-                    "type": "string"
-                },
-                "numberOfSteps": {
-                    "type": "integer"
-                }
-            }
-        },
-        "NsScaleResponse": {
-            "type": "object",
-            "properties": {
-                "jobID": {
-                    "type": "string"
-                }
-            }
-        },
-        "NsTerminateRequest": {
-            "type": "object",
-            "properties": {
-                "terminationType": {
-                    "type": "string"
-                },
-                "gracefulTerminationTimeout": {
-                    "type": "string"
-                }
-            }
-        },
-        "NsTerminateResponse": {
-            "type": "object",
-            "properties": {
-                "jobID": {
-                    "type": "string"
-                }
-            }
-        },
-        "healVnfDataRequest": {
-            "type": "object",
-            "properties": {
-                "vnfInstanceId": {
-                    "type": "string"
-                },
-                "cause": {
-                    "type": "string"
-                },
-                "additionalParams": {
-                    "type": "object",
-                    "properties": {
-                        "action": {
-                            "type": "string"
-                        },
-                        "actionvminfo": {
-                            "type": "object",
-                            "properties": {
-                                "vmid": {
-                                    "type": "string"
-                                },
-                                "vmname": {
-                                    "type": "string"
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        },
-        "healVnfDataResponse": {
-            "type": "object",
-            "properties": {
-                "jobId": {
-                    "type": "string"
-                }
-            }
-        },
-        "TableInfo": {
-            "type": "object",
-            "properties": {
-                "count": {
-                    "type": "string"
-                }
-            }
-        },
-        "NsInfo": {
-            "type": "object",
-            "properties": {
-                "vnfInfoId": {
-                    "type": "string"
-                },
-                "vlInfo": {
-                    "type": "string"
-                },
-                "nsState": {
-                    "type": "string"
-                },
-                "description": {
-                    "type": "string"
-                },
-                "nsName": {
-                    "type": "string"
-                },
-                "nsInstanceId": {
-                    "type": "string"
-                },
-                "nsdId": {
-                    "type": "string"
-                },
-                "vnffgInfo": {
-                    "type": "string"
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
index a18efcc..f2025bf 100644 (file)
@@ -19,7 +19,6 @@ from lcm.ns.views import CreateNSView, NSInstView, TerminateNSView, NSDetailView
 
 urlpatterns = patterns('',
                        url(r'^api/nslcm/v1/ns$', CreateNSView.as_view()),
-                       url(r'^api/nslcm/v1/swagger.json$', SwaggerJsonView.as_view()),
                        url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/instantiate$',
                            NSInstView.as_view()),
                        url(r'^api/nslcm/v1/ns/(?P<ns_instance_id>[0-9a-zA-Z_-]+)/terminate$',
index 8e7bad0..2e922d4 100644 (file)
@@ -165,7 +165,7 @@ class TestNfPackage(TestCase):
             "vimIds": ["1"]
             }, format='json')
         self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
-"""
+
     @mock.patch.object(restcall, 'call_req')
     def test_nf_pkg_on_boarding_when_on_boarded(self, mock_call_req):
         mock_call_req.return_value = [0, json.JSONEncoder().encode({"onBoardState": "onBoarded"}), '200']
@@ -190,7 +190,7 @@ class TestNfPackage(TestCase):
     @mock.patch.object(restcall, 'call_req')
     def test_nf_on_boarding_when_nfd_already_exists(self, mock_call_req):
         mock_vals = {
-            "/api/catalog/v0/csars/2":
+            "/api/catalog/v1/csars/2":
                 [0, json.JSONEncoder().encode({
                     "onBoardState": "onBoardFailed", "processState": "deleteFailed"}), '200'],
             "/api/catalog/v1/servicetemplates/queryingrawdata":
@@ -467,5 +467,5 @@ class TestNfPackage(TestCase):
         self.assertEqual(1, len(resp.data["csars"]))
         self.assertEqual("1", resp.data["csars"][0]["csarId"])
         self.assertEqual("2", resp.data["csars"][0]["vnfdId"])
-"""       
+       
         
index 1747be0..1ae8e13 100644 (file)
@@ -254,7 +254,7 @@ class TestNfPackage(TestCase):
             "vimIds": ["1"]
             }, format='json')
         self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
-    """
+    
     def test_nf_pkg_distribute_when_csar_already_exist(self):
         NfPackageModel(uuid="1", nfpackageid="1", vnfdid="vcpe_vfw_zte_1_0").save()
         SdcNfDistributeThread(csar_id="1",
@@ -297,7 +297,6 @@ class TestNfPackage(TestCase):
                            lab_vim_id="",
                            job_id="4").run()
         self.assert_job_result("4", 100, "CSAR(1) distribute successfully.")
-    """
 
     ###############################################################################################################
 
@@ -305,7 +304,7 @@ class TestNfPackage(TestCase):
     def test_nf_pkg_delete_normal(self, mock_run):
         resp = self.client.delete("/api/nslcm/v1/vnfpackage/1")
         self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
-    """
+    
     def test_nf_pkg_normal_delete(self):
         NfPackageModel(uuid="2", nfpackageid="2", vnfdid="vcpe_vfw_zte_1_0").save()
         SdcNfPkgDeleteThread(csar_id="2", job_id="2", force_delete=False).run()
@@ -322,7 +321,6 @@ class TestNfPackage(TestCase):
         NfInstModel(nfinstid="3", package_id="3").save()
         SdcNfPkgDeleteThread(csar_id="3", job_id="2", force_delete=False).run()
         self.assert_job_result("2", 255, "NfInst by csar(3) exists, cannot delete.")
-    """
 
     def test_nf_pkg_get_all(self):
         NfPackageModel(uuid="3", nfpackageid="3", vnfdid="4").save()
index f501d33..b5941b7 100644 (file)
@@ -63,6 +63,9 @@ SDC_PASSWD = "admin"
 
 # [workflow]
 DEPLOY_WORKFLOW_WHEN_START = True
+# Support option: activiti/wso2/buildin
+WORKFLOW_OPTION = "activiti"
+
 
 
 
index 5f08d0b..6f63a48 100644 (file)
@@ -35,10 +35,7 @@ class VimAdaptor:
     def create_api(self, connectInfo):
         vimtype = connectInfo['vimtype'] if 'vimtype' in connectInfo else None
         logger.info("call %s, vimtype=%s" % (fun_name(), vimtype))
-        if vimtype == const.VIM_OPENSTACK:
-            from lcm.pub.nfvi.vim.api.openstack.api import OpenstackApi
-            self.apiImpl = OpenstackApi()
-        elif vimtype == const.VIM_VMWARE:
+        if vimtype in (const.VIM_OPENSTACK, const.VIM_VMWARE):
             from lcm.pub.nfvi.vim.api.multivim.api import MultiVimApi
             self.apiImpl = MultiVimApi()
         else:
index b224f4e..919e95e 100644 (file)
 # limitations under the License.
 import json
 
-from lcm.pub.utils.toscaparser.convert import convert_nsd, convert_vnfd
 from lcm.pub.utils.toscaparser.nsdmodel import EtsiNsdInfoModel
 from lcm.pub.utils.toscaparser.vnfdmodel import EtsiVnfdInfoModel
-from lcm.pub.utils.toscaparser.parser import parse_nsd_model, parse_vnfd_model
 
 
 def parse_nsd(path, input_parameters=[]):
@@ -31,4 +29,3 @@ def parse_vnfd(path, input_parameters=[]):
     strResponse = json.dumps(tosca_obj, default=lambda obj: obj.__dict__)
     strResponse = strResponse.replace(': null', ': ""')
     return strResponse
-
index e624bd0..452e6e3 100644 (file)
@@ -188,6 +188,9 @@ class BaseInfoModel(object):
         return node['nodeType'].upper().find('.VIRTUALLINK.') >= 0 or node['nodeType'].upper().find('.VL.') >= 0 or \
                node['nodeType'].upper().endswith('.VIRTUALLINK') or node['nodeType'].upper().endswith('.VL')
 
+    def isService(self, node):
+        return node['nodeType'].upper().find('.SERVICE.') >= 0 or node['nodeType'].upper().endswith('.SERVICE')
+
     def get_requirement_node_name(self, req_value):
         return self.get_prop_from_obj(req_value, 'node')
 
index ae902df..ce6a8aa 100644 (file)
@@ -21,14 +21,13 @@ class EtsiNsdInfoModel(BaseInfoModel):
         self.pnfs = self._get_all_pnf(nodeTemplates)
         self.vls = self.get_all_vl(nodeTemplates)
         self.cps = self.get_all_cp(nodeTemplates)
-        # self.routers = self.get_all_router(nodeTemplates)
-        # self.fps = self._get_all_fp(nodeTemplates)
-        # self.vnffgs = self._get_all_vnffg(tosca.topology_template.groups)
-        # self.server_groups = self.get_all_server_group(tosca.topology_template.groups)
-        # self.ns_exposed = self.get_all_endpoint_exposed(tosca.topology_template)
-        # self.policies = self._get_policies_scaling(tosca.topology_template.policies)
-        # self.ns_flavours = self.get_all_flavour(tosca.topology_template.groups)
-        # self.nested_ns = self.get_all_nested_ns(nodeTemplates)
+        self.routers = self.get_all_router(nodeTemplates)
+        self.fps = self._get_all_fp(nodeTemplates)
+        self.vnffgs = self._get_all_vnffg(tosca.topology_template.groups)
+        self.server_groups = self.get_all_server_group(tosca.topology_template.groups)
+        self.ns_exposed = self.get_all_endpoint_exposed(tosca.topology_template)
+        self.policies = self._get_policies_scaling(tosca.topology_template.policies)
+
 
     def buildInputs(self, top_inputs):
         ret = {}
@@ -168,4 +167,162 @@ class EtsiNsdInfoModel(BaseInfoModel):
             node = self.get_node_by_name(node_templates, node_id)
             if self.isPnf(node):
                 return node_id
-        return ""
\ No newline at end of file
+        return ""
+
+    def get_all_router(self, nodeTemplates):
+        rets = []
+        for node in nodeTemplates:
+            if self._isRouter(node):
+                ret = {}
+                ret['router_id'] = node['name']
+                ret['description'] = node['description']
+                ret['properties'] = node['properties']
+                ret['external_vl_id'] = self._get_router_external_vl_id(node)
+                ret['external_ip_addresses'] = self._get_external_ip_addresses(node)
+
+                rets.append(ret)
+        return rets
+
+    def _isRouter(self, node):
+        return node['nodeType'].upper().find('.ROUTER.') >= 0 or node['nodeType'].upper().endswith('.ROUTER')
+
+    def _get_router_external_vl(self, node):
+        return self.getRequirementByName(node, 'external_virtual_link')
+
+    def _get_router_external_vl_id(self, node):
+        ids = map(lambda x: self.get_requirement_node_name(x), self._get_router_external_vl(node))
+        if len(ids) > 0:
+            return ids[0]
+        return ""
+
+    def _get_external_ip_addresses(self, node):
+        external_vls = self._get_router_external_vl(node)
+        if len(external_vls) > 0:
+            if 'relationship' in external_vls[0] and 'properties' in external_vls[0]['relationship'] and 'router_ip_address' in external_vls[0]['relationship']['properties']:
+                return external_vls[0]['relationship']['properties']['router_ip_address']
+        return []
+
+    def _get_all_fp(self, nodeTemplates):
+        fps = []
+        for node in nodeTemplates:
+            if self._isFp(node):
+                fp = {}
+                fp['fp_id'] = node['name']
+                fp['description'] = node['description']
+                fp['properties'] = node['properties']
+                fp['forwarder_list'] = self._getForwarderList(node, nodeTemplates)
+
+                fps.append(fp)
+        return fps
+
+    def _isFp(self, node):
+        return node['nodeType'].upper().find('.FP.') >= 0 or node['nodeType'].upper().find('.SFP.') >= 0 or node[
+            'nodeType'].upper().endswith('.FP') or node['nodeType'].upper().endswith('.SFP')
+
+    def _getForwarderList(self, node, node_templates):
+        forwarderList = []
+        if 'requirements' in node:
+            for item in node['requirements']:
+                for key, value in item.items():
+                    if key == 'forwarder':
+                        tmpnode = self.get_node_by_req(node_templates, value)
+                        type = 'cp' if self.isCp(tmpnode) else 'vnf'
+                        req_node_name = self.get_requirement_node_name(value)
+                        if isinstance(value, dict) and 'capability' in value:
+                            forwarderList.append(
+                                {"type": type, "node_name": req_node_name, "capability": value['capability']})
+                        else:
+                            forwarderList.append({"type": type, "node_name": req_node_name, "capability": ""})
+
+        return forwarderList
+
+    def get_node_by_req(self, node_templates, req):
+        req_node_name = self.get_requirement_node_name(req)
+        return self.get_node_by_name(node_templates, req_node_name)
+
+    def _get_all_vnffg(self, groups):
+        vnffgs = []
+        for group in groups:
+            if self._isVnffg(group):
+                vnffg = {}
+                vnffg['vnffg_id'] = group.name
+                vnffg['description'] = group.description
+                if 'properties' in group.tpl:
+                    vnffg['properties'] = group.tpl['properties']
+                vnffg['members'] = group.members
+
+                vnffgs.append(vnffg)
+        return vnffgs
+
+    def _isVnffg(self, group):
+        return group.type.upper().find('.VNFFG.') >= 0 or group.type.upper().find(
+            '.SFC.') >= 0 or group.type.upper().endswith('.VNFFG') or group.type.upper().endswith('.SFC')
+
+    def get_all_server_group(self, groups):
+        rets = []
+        for group in groups:
+            if self._isServerGroup(group):
+                ret = {}
+                ret['group_id'] = group.name
+                ret['description'] = group.description
+                if 'properties' in group.tpl:
+                    ret['properties'] = group.tpl['properties']
+                ret['members'] = group.members
+
+                rets.append(ret)
+        return rets
+
+    def _isServerGroup(self, group):
+        return group.type.upper().find('.AFFINITYORANTIAFFINITYGROUP.') >= 0 or group.type.upper().endswith(
+            '.AFFINITYORANTIAFFINITYGROUP')
+
+    def get_all_endpoint_exposed(self, topo_tpl):
+        if 'substitution_mappings' in topo_tpl.tpl:
+            external_cps = self._get_external_cps(topo_tpl.tpl['substitution_mappings'])
+            forward_cps = self._get_forward_cps(topo_tpl.tpl['substitution_mappings'])
+            return {"external_cps": external_cps, "forward_cps": forward_cps}
+        return {}
+
+    def _get_external_cps(self, subs_mappings):
+        external_cps = []
+        if 'requirements' in subs_mappings:
+            for key, value in subs_mappings['requirements'].items():
+                if isinstance(value, list) and len(value) > 0:
+                    external_cps.append({"key_name": key, "cpd_id": value[0]})
+                else:
+                    external_cps.append({"key_name": key, "cpd_id": value})
+        return external_cps
+
+    def _get_forward_cps(self, subs_mappings):
+        forward_cps = []
+        if 'capabilities' in subs_mappings:
+            for key, value in subs_mappings['capabilities'].items():
+                if isinstance(value, list) and len(value) > 0:
+                    forward_cps.append({"key_name": key, "cpd_id": value[0]})
+                else:
+                    forward_cps.append({"key_name": key, "cpd_id": value})
+        return forward_cps
+
+    def _get_policies_scaling(self, top_policies):
+        policies_scaling = []
+        scaling_policies = self.get_scaling_policies(top_policies)
+        if len(scaling_policies) > 0:
+            policies_scaling.append({"scaling": scaling_policies})
+        return policies_scaling
+
+    def get_policies_by_keyword(self, top_policies, keyword):
+        ret = []
+        for policy in top_policies:
+            if policy.type.upper().find(keyword) >= 0:
+                tmp = {}
+                tmp['policy_id'] = policy.name
+                tmp['description'] = policy.description
+                if 'properties' in policy.entity_tpl:
+                    tmp['properties'] = policy.entity_tpl['properties']
+                tmp['targets'] = policy.targets
+                ret.append(tmp)
+
+        return ret
+
+    def get_scaling_policies(self, top_policies):
+        return self.get_policies_by_keyword(top_policies, '.SCALING')
\ No newline at end of file
index 39e9a18..eac1f0b 100644 (file)
@@ -1,3 +1,5 @@
+import functools
+
 from lcm.pub.utils.toscaparser import EtsiNsdInfoModel
 
 
@@ -5,3 +7,30 @@ class EtsiVnfdInfoModel(EtsiNsdInfoModel):
 
     def __init__(self, path, params):
         super(EtsiVnfdInfoModel, self).__init__(path, params)
+
+    def parseModel(self, tosca):
+        self.buidMetadata(tosca)
+        if hasattr(tosca, 'topology_template') and hasattr(tosca.topology_template, 'inputs'):
+            self.inputs = self.buildInputs(tosca.topology_template.inputs)
+
+        nodeTemplates = map(functools.partial(self.buildNode, inputs=tosca.inputs, parsed_params=tosca.parsed_params),
+                            tosca.nodetemplates)
+
+        self.services = self._get_all_services(nodeTemplates)
+
+
+    def _get_all_services(self, nodeTemplates):
+        ret = []
+        for node in nodeTemplates:
+            if self.isService(node):
+                service = {}
+                service['serviceId'] = node['name']
+                if 'description' in node:
+                    service['description'] = node['description']
+                service['properties'] = node['properties']
+                service['dependencies'] = map(lambda x: self.get_requirement_node_name(x),
+                                              self.getNodeDependencys(node))
+                service['networks'] = map(lambda x: self.get_requirement_node_name(x), self.getVirtualLinks(node))
+
+                ret.append(service)
+        return ret
\ No newline at end of file
index 1cf1371..8f9f732 100644 (file)
@@ -45,7 +45,8 @@ INSTALLED_APPS = [
     'django.contrib.staticfiles',
     'rest_framework',
     'lcm.pub.database',
-    'lcm.samples'
+    'lcm.samples',
+    'lcm.swagger'
 ]
 
 MIDDLEWARE_CLASSES = [
diff --git a/lcm/swagger/__init__.py b/lcm/swagger/__init__.py
new file mode 100644 (file)
index 0000000..49c7b94
--- /dev/null
@@ -0,0 +1,10 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lcm/swagger/tests.py b/lcm/swagger/tests.py
new file mode 100644 (file)
index 0000000..b877609
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+import unittest
+import json
+from django.test import Client
+from rest_framework import status
+
+
+class SampleViewTest(unittest.TestCase):
+    def setUp(self):
+        self.client = Client()
+
+    def tearDown(self):
+        pass
+
+    def test_sample(self):
+        response = self.client.get("/api/nslcm/v1/swagger.json")
+        print response
+        self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
+#        resp_data = json.loads(response.content)
+#        self.assertEqual({"status": "active"}, resp_data)
diff --git a/lcm/swagger/urls.py b/lcm/swagger/urls.py
new file mode 100644 (file)
index 0000000..c3b8ad6
--- /dev/null
@@ -0,0 +1,23 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from django.conf.urls import patterns, url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from lcm.swagger.views import SwaggerJsonView
+
+urlpatterns = patterns('',
+                       url(r'^api/nslcm/v1/swagger.json$', SwaggerJsonView.as_view())
+                       )
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/lcm/swagger/vfc.db.swagger.json b/lcm/swagger/vfc.db.swagger.json
new file mode 100644 (file)
index 0000000..98f7696
--- /dev/null
@@ -0,0 +1,758 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "version": "1.0.0",
+        "title": "ONAP VFC Service Internal Rest API"
+    },
+    "basePath": "/api/nslcm/v1",
+    "paths": {
+        "/ns/vls": {
+            "post": {
+                "tags": [
+                    "vls"
+                ],
+                "summary": "vl create",
+                "description": "",
+                "operationId": "create_vl",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "instantiate request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/VlPostRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "",
+                        "schema": {
+                            "$ref": "#/definitions/VlPostResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/ns/vls/{vlId}": {
+            "get": {
+                "tags": [
+                    "vls"
+                ],
+                "summary": "query the specified vl info",
+                "description": "",
+                "operationId": "query_vl",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "vlId",
+                        "in": "path",
+                        "description": "vl instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/VlInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the vl instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "vls"
+                ],
+                "summary": "delete vl",
+                "description": "",
+                "operationId": "delete_vl",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "vlId",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/DeleteVlResponse"
+                        }
+                    },
+                    "404": {
+                        "description": "the vl instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            }
+        },
+        "/ns/vnfs": {
+            "post": {
+                "tags": [
+                    "vnfs"
+                ],
+                "summary": "vnf create",
+                "description": "",
+                "operationId": "create_vnf",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "instantiate request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/VnfPostRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "",
+                        "schema": {
+                            "$ref": "#/definitions/VnfPostResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/ns/vnfs/{vnfInstId}": {
+            "get": {
+                "tags": [
+                    "vnfs"
+                ],
+                "summary": "query the specified vnf info",
+                "description": "",
+                "operationId": "query_vnf",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "vnfInstId",
+                        "in": "path",
+                        "description": "vnf instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/VnfInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the vnf instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "vnfs"
+                ],
+                "summary": "delete vnf",
+                "description": "",
+                "operationId": "delete_vnf",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "vnfInstId",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/DeleteResponse"
+                        }
+                    },
+                    "404": {
+                        "description": "the vl instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            }
+        },
+        "/ns/sfcs": {
+            "post": {
+                "tags": [
+                    "sfcs"
+                ],
+                "summary": "sfc create",
+                "description": "",
+                "operationId": "create_sfc",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/SfcPostRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "",
+                        "schema": {
+                            "$ref": "#/definitions/SfcPostResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/ns/sfcs/{sfcInstId}": {
+            "get": {
+                "tags": [
+                    "sfcs"
+                ],
+                "summary": "query the specified sfc info",
+                "description": "",
+                "operationId": "query_sfc",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "sfcInstId",
+                        "in": "path",
+                        "description": "sfc instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/SfcInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the sfc instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "vnfs"
+                ],
+                "summary": "delete sfc",
+                "description": "",
+                "operationId": "delete_sfc",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "sfcInstId",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/DeleteResponse"
+                        }
+                    },
+                    "404": {
+                        "description": "the sfc instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            }
+        },
+        "/ns/{nsInstanceId}/postdeal": {
+            "post": {
+                "tags": [
+                    "postdeal"
+                ],
+                "summary": "ns postdeal",
+                "description": "",
+                "operationId": "ns_postdeal",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "nsInstanceId",
+                        "in": "path"
+                    },
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/NSInstPostDetailRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "202": {
+                        "description": ""
+                    }
+                }
+            }
+        },
+        "/mandb/{modelName}": {
+            "get": {
+                "tags": [
+                    "db"
+                ],
+                "summary": "query ns table info",
+                "description": "query ns table info",
+                "operationId": "query_ns_table",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "model Name.",
+                        "name": "modelName",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/TableInfo"
+                        }
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "db"
+                ],
+                "summary": "ns table delete",
+                "description": "ns table delete",
+                "operationId": "ns_table_delete",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "model Name.",
+                        "name": "modelName",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "The tables were deleted successfully."
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "VlPostRequest": {
+            "type": "object",
+            "properties": {
+                "jobId": {
+                    "type": "string"
+                },
+                "nsInstanceId": {
+                    "type": "string"
+                },
+                "flavourId": {
+                    "type": "string"
+                },
+                "sapData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "pnfInfo": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "vnfInstanceData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "nestedNsInstanceId": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "locationConstraints": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForNs": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForVnf": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "extNSVirtualLink": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "context": {
+                    "type": "string"
+                },
+                "vlIndex": {
+                    "type": "string"
+                }
+            }
+        },
+        "VlPostResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                },
+                "vlId": {
+                    "type": "string"
+                }
+            }
+        },
+        "VnfPostRequest": {
+            "type": "object",
+            "properties": {
+                "jobId": {
+                    "type": "string"
+                },
+                "nsInstanceId": {
+                    "type": "string"
+                },
+                "flavourId": {
+                    "type": "string"
+                },
+                "sapData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "pnfInfo": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "vnfInstanceData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "nestedNsInstanceId": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "locationConstraints": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForNs": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForVnf": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "extNSVirtualLink": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "context": {
+                    "type": "string"
+                },
+                "vnfIndex": {
+                    "type": "string"
+                }
+            }
+        },
+        "VnfPostResponse": {
+            "type": "object",
+            "properties": {
+                "vnfInstId": {
+                    "type": "string"
+                },
+                "jobId": {
+                    "type": "string"
+                }
+            }
+        },
+        "SfcPostRequest": {
+            "type": "object",
+            "properties": {
+                "jobId": {
+                    "type": "string"
+                },
+                "nsInstanceId": {
+                    "type": "string"
+                },
+                "sapData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "vnfInstanceData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForNs": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForVnf": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "sdnControllerId": {
+                    "type": "string"
+                },
+                "context": {
+                    "type": "string"
+                },
+                "fpindex": {
+                    "type": "string"
+                }
+            }
+        },
+        "NSInstPostDetailRequest": {
+            "type": "object",
+            "properties": {
+                "status": {
+                    "type": "string"
+                }
+            }
+        },
+
+        "SfcPostResponse": {
+            "type": "object",
+            "properties": {
+                "sfcInstId": {
+                    "type": "string"
+                },
+                "jobId": {
+                    "type": "string"
+                }
+            }
+        },
+        "VlInfo": {
+            "type": "object",
+            "properties": {
+                "vlId": {
+                    "type": "string"
+                },
+                "vlName": {
+                    "type": "string"
+                },
+                "vlStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        "VnfInfo": {
+            "type": "object",
+            "properties": {
+                "vnfInstId": {
+                    "type": "string"
+                },
+                "vnfName": {
+                    "type": "string"
+                },
+                "vnfStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        "SfcInfo": {
+            "type": "object",
+            "properties": {
+                "sfcInstId": {
+                    "type": "string"
+                },
+                "sfcName": {
+                    "type": "string"
+                },
+                "sfcStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        "DeleteVlResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                }
+            }
+        },
+        "DeleteResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                }
+            }
+        },
+
+        "TableInfo": {
+            "type": "object",
+            "properties": {
+                "count": {
+                    "type": "string"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lcm/swagger/vfc.nslcm.swagger.json b/lcm/swagger/vfc.nslcm.swagger.json
new file mode 100644 (file)
index 0000000..75cc6ba
--- /dev/null
@@ -0,0 +1,537 @@
+{\r
+  "swagger": "2.0",\r
+  "info": {\r
+    "version": "1.0.0",\r
+    "title": "ONAP VFC Network Service Lifecycle Management API",\r
+    "description": "VFC Network Service Lifecycle Management Rest API.",\r
+    "contact": {\r
+      "name": "ONAP VFC team",\r
+      "email": "onap-discuss@lists.onap.org",\r
+      "url": "https://gerrit.onap.org/r/#/admin/projects/vfc/nfvo/lcm"\r
+    }\r
+  },\r
+  "basePath": "/api/nslcm/v1",\r
+  "schemes": [\r
+    "http",\r
+    "https"\r
+  ],\r
+  "consumes": [\r
+    "application/json"\r
+  ],\r
+  "produces": [\r
+    "application/json"\r
+  ],\r
+  "paths": {\r
+    "/ns": {\r
+      "post": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns create",\r
+        "description": "ns create",\r
+        "operationId": "ns_create",\r
+        "parameters": [\r
+          {\r
+            "in": "body",\r
+            "name": "NSCreateRequest",\r
+            "description": "NS Instance Create Request",\r
+            "required": true,\r
+            "schema": {\r
+              "$ref": "#/definitions/NsCreateRequest"\r
+            }\r
+          }\r
+        ],\r
+        "responses": {\r
+          "200": {\r
+            "description": "successful operation",\r
+            "schema": {\r
+              "$ref": "#/definitions/NsCreateResponse"\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "get": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns get",\r
+        "description": "ns get",\r
+        "operationId": "ns_get",\r
+        "parameters": [],\r
+        "responses": {\r
+          "200": {\r
+            "description": "successful operation",\r
+            "schema": {\r
+              "$ref": "#/definitions/NsInfo"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/ns/{nsInstanceId}/Instantiate": {\r
+      "post": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns Instantiate",\r
+        "description": "ns Instantiate",\r
+        "operationId": "ns_Instantiate",\r
+        "parameters": [\r
+          {\r
+            "required": true,\r
+            "type": "string",\r
+            "description": "",\r
+            "name": "nsInstanceId",\r
+            "in": "path"\r
+          },\r
+          {\r
+            "in": "body",\r
+            "name": "NSInstantiateRequest",\r
+            "description": "NS Instantiate Request Body",\r
+            "required": true,\r
+            "schema": {\r
+              "$ref": "#/definitions/NsInstantiateRequest"\r
+            }\r
+          }\r
+        ],\r
+        "responses": {\r
+          "200": {\r
+            "description": "",\r
+            "schema": {\r
+              "$ref": "#/definitions/JobInfo"\r
+            }\r
+          },\r
+          "201": {\r
+            "description": "Invalid Request"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/ns/{nsInstanceId}/scale": {\r
+      "post": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns scale",\r
+        "description": "ns scale",\r
+        "operationId": "ns_scale",\r
+        "parameters": [\r
+          {\r
+            "required": true,\r
+            "type": "string",\r
+            "description": "",\r
+            "name": "nsInstanceId",\r
+            "in": "path"\r
+          },\r
+          {\r
+            "in": "body",\r
+            "name": "ScaleNSRequest",\r
+            "description": "Scale NS Request Body",\r
+            "required": true,\r
+            "schema": {\r
+              "$ref": "#/definitions/NsScaleRequest"\r
+            }\r
+          }\r
+        ],\r
+        "responses": {\r
+          "200": {\r
+            "description": "",\r
+            "schema": {\r
+              "$ref": "#/definitions/JobInfo"\r
+            }\r
+          },\r
+          "201": {\r
+            "description": "Invalid Request"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/ns/{ns_instance_id}/heal": {\r
+      "post": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns heal",\r
+        "description": "ns heal",\r
+        "operationId": "ns_heal",\r
+        "parameters": [\r
+          {\r
+            "required": true,\r
+            "type": "string",\r
+            "description": "Identifier of the NS instance.",\r
+            "name": "ns_instance_id",\r
+            "in": "path"\r
+          },\r
+          {\r
+            "in": "body",\r
+            "name": "healVnfData",\r
+            "description": "healVnfData",\r
+            "required": true,\r
+            "schema": {\r
+              "$ref": "#/definitions/NsHealRequest"\r
+            }\r
+          }\r
+        ],\r
+        "responses": {\r
+          "202": {\r
+            "description": "",\r
+            "schema": {\r
+              "$ref": "#/definitions/JobInfo"\r
+            }\r
+          },\r
+          "500": {\r
+            "description": "the url is invalid"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/ns/{ns_instance_id}/terminate": {\r
+      "post": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns terminate",\r
+        "description": "ns terminate",\r
+        "operationId": "ns_terminate",\r
+        "parameters": [\r
+          {\r
+            "required": true,\r
+            "type": "string",\r
+            "description": "Identifier of the NS instance.",\r
+            "name": "ns_instance_id",\r
+            "in": "path"\r
+          },\r
+          {\r
+            "in": "body",\r
+            "name": "NsTerminateRequest",\r
+            "description": "NsTerminateRequest",\r
+            "required": true,\r
+            "schema": {\r
+              "$ref": "#/definitions/NsTerminateRequest"\r
+            }\r
+          }\r
+        ],\r
+        "responses": {\r
+          "202": {\r
+            "description": "",\r
+            "schema": {\r
+              "$ref": "#/definitions/JobInfo"\r
+            }\r
+          },\r
+          "500": {\r
+            "description": "the url is invalid"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/ns/{ns_instance_id}": {\r
+      "delete": {\r
+        "tags": [\r
+          "ns"\r
+        ],\r
+        "summary": "ns delete",\r
+        "description": "ns delete",\r
+        "operationId": "ns_delete",\r
+        "parameters": [\r
+          {\r
+            "required": true,\r
+            "type": "string",\r
+            "description": "Identifier of the NS instance.",\r
+            "name": "ns_instance_id",\r
+            "in": "path"\r
+          }\r
+        ],\r
+        "responses": {\r
+          "204": {\r
+            "description": "The NS instance resource and the associated NS identifier were deleted successfully."\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/jobs/{jobId}": {\r
+      "post": {\r
+        "tags": [\r
+          "job"\r
+        ],\r
+        "summary": "jobstatus",\r
+        "description": "",\r
+        "operationId": "jobstatus",\r
+        "parameters": [\r
+          {\r
+            "required": true,\r
+            "type": "string",\r
+            "description": "",\r
+            "name": "jobId",\r
+            "in": "path"\r
+          },\r
+          {\r
+            "in": "body",\r
+            "name": "body",\r
+            "description": "request param",\r
+            "required": true,\r
+            "schema": {\r
+              "$ref": "#/definitions/JobProgressRequest"\r
+            }\r
+          }\r
+        ],\r
+        "responses": {\r
+          "202": {\r
+            "description": ""\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "definitions": {\r
+    "NsCreateRequest": {\r
+      "type": "object",\r
+      "properties": {\r
+        "csarId": {\r
+          "type": "string",\r
+          "description": "the NS package ID"\r
+        },\r
+        "nsName": {\r
+          "type": "string"\r
+        },\r
+        "description": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "NsCreateResponse": {\r
+      "type": "object",\r
+      "properties": {\r
+        "nsInstanceId": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "NsInstantiateRequest": {\r
+      "type": "object",\r
+      "properties": {\r
+        "LocationConstraints": {\r
+          "type": "array",\r
+          "items": {\r
+            "$ref": "#/definitions/LocationConstraint"\r
+          }\r
+        },\r
+        "additionalParamForNs": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "LocationConstraint": {\r
+      "type": "object",\r
+      "properties": {\r
+        "vnfProfileId": {\r
+          "type": "string"\r
+        },\r
+        "locationConstraints": {\r
+          "type": "object",\r
+          "properties": {\r
+            "vimid": {\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "NsScaleRequest": {\r
+      "type": "object",\r
+      "properties": {\r
+        "scaleType": {\r
+          "type": "string"\r
+        },\r
+        "scaleNsByStepsData": {\r
+          "$ref": "#/definitions/NsScaleByStepsData"\r
+        }\r
+      }\r
+    },\r
+    "NsScaleByStepsData": {\r
+      "type": "object",\r
+      "properties": {\r
+        "scalingDirection": {\r
+          "type": "string"\r
+        },\r
+        "aspectId": {\r
+          "type": "string"\r
+        },\r
+        "numberOfSteps": {\r
+          "type": "integer"\r
+        }\r
+      }\r
+    },\r
+    "NsHealRequest": {\r
+      "type": "object",\r
+      "properties": {\r
+        "vnfInstanceId": {\r
+          "type": "string"\r
+        },\r
+        "cause": {\r
+          "type": "string"\r
+        },\r
+        "additionalParams": {\r
+          "type": "object",\r
+          "properties": {\r
+            "action": {\r
+              "type": "string"\r
+            },\r
+            "actionvminfo": {\r
+              "type": "object",\r
+              "properties": {\r
+                "vmid": {\r
+                  "type": "string"\r
+                },\r
+                "vmname": {\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "NsTerminateRequest": {\r
+      "type": "object",\r
+      "properties": {\r
+        "terminationType": {\r
+          "type": "string"\r
+        },\r
+        "gracefulTerminationTimeout": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "JobInfo": {\r
+      "type": "object",\r
+      "properties": {\r
+        "jobId": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "JobProgressRequest": {\r
+      "type": "object",\r
+      "properties": {\r
+        "progress": {\r
+          "type": "string"\r
+        },\r
+        "desc": {\r
+          "type": "string"\r
+        },\r
+        "errcode": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "NsInfo": {\r
+      "type": "object",\r
+      "properties": {\r
+        "nsInstanceId": {\r
+          "type": "string"\r
+        },\r
+        "nsName": {\r
+          "type": "string"\r
+        },\r
+        "description": {\r
+          "type": "string"\r
+        },\r
+        "nsdId": {\r
+          "type": "string"\r
+        },\r
+        "vnfInfo": {\r
+          "type": "array",\r
+          "items": {\r
+            "$ref": "#/definitions/vnfInfo"\r
+          }\r
+        },\r
+        "vlInfo": {\r
+          "type": "array",\r
+          "items": {\r
+            "$ref": "#/definitions/vlInfo"\r
+          }\r
+        },\r
+        "vnffgInfo": {\r
+          "type": "array",\r
+          "items": {\r
+            "$ref": "#/definitions/vnffgInfo"\r
+          }\r
+        },\r
+        "nsState": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "vnfInfo": {\r
+      "type": "object",\r
+      "properties": {\r
+        "vnfInstanceId": {\r
+          "type": "string"\r
+        },\r
+        "vnfInstanceName": {\r
+          "type": "string"\r
+        },\r
+        "vnfdId": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "vlInfo": {\r
+      "type": "object",\r
+      "properties": {\r
+        "vlInstanceId": {\r
+          "type": "string"\r
+        },\r
+        "vlInstanceName": {\r
+          "type": "string"\r
+        },\r
+        "vldId": {\r
+          "type": "string"\r
+        },\r
+        "relatedCpInstanceId": {\r
+          "type": "array",\r
+          "items": {\r
+            "$ref": "#/definitions/cpInfo"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "cpInfo": {\r
+      "type": "object",\r
+      "properties": {\r
+        "cpInstanceId": {\r
+          "type": "string"\r
+        },\r
+        "cpInstanceName": {\r
+          "type": "string"\r
+        },\r
+        "cpdId": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    },\r
+    "vnffgInfo": {\r
+      "type": "object",\r
+      "properties": {\r
+        "vnffgInstanceId": {\r
+          "type": "string"\r
+        },\r
+        "vnfId": {\r
+          "type": "string"\r
+        },\r
+        "pnfId": {\r
+          "type": "string"\r
+        },\r
+        "virtualLinkId": {\r
+          "type": "string"\r
+        },\r
+        "cpId": {\r
+          "type": "string"\r
+        },\r
+        "nfp": {\r
+          "type": "string"\r
+        }\r
+      }\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/lcm/swagger/vfc.others.swagger.json b/lcm/swagger/vfc.others.swagger.json
new file mode 100644 (file)
index 0000000..9be7490
--- /dev/null
@@ -0,0 +1,135 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "version": "1.0.0",
+        "title": "ONAP VFC Service Internal Rest API"
+    },
+    "basePath": "/api/nslcm/v1",
+    "paths": {
+        "/ns/{nsInstanceId}/postdeal": {
+            "post": {
+                "tags": [
+                    "postdeal"
+                ],
+                "summary": "ns postdeal",
+                "description": "",
+                "operationId": "ns_postdeal",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "nsInstanceId",
+                        "in": "path"
+                    },
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/NSInstPostDetailRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "202": {
+                        "description": ""
+                    }
+                }
+            }
+        },
+        "/mandb/{modelName}": {
+            "get": {
+                "tags": [
+                    "db"
+                ],
+                "summary": "query ns table info",
+                "description": "query ns table info",
+                "operationId": "query_ns_table",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "model Name.",
+                        "name": "modelName",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/TableInfo"
+                        }
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "db"
+                ],
+                "summary": "ns table delete",
+                "description": "ns table delete",
+                "operationId": "ns_table_delete",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "model Name.",
+                        "name": "modelName",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "The tables were deleted successfully."
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+
+        "NSInstPostDetailRequest": {
+            "type": "object",
+            "properties": {
+                "status": {
+                    "type": "string"
+                }
+            }
+        },
+
+
+        "TableInfo": {
+            "type": "object",
+            "properties": {
+                "count": {
+                    "type": "string"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lcm/swagger/vfc.sfclcm.swagger.json b/lcm/swagger/vfc.sfclcm.swagger.json
new file mode 100644 (file)
index 0000000..af06543
--- /dev/null
@@ -0,0 +1,237 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "version": "1.0.0",
+        "title": "ONAP VFC Service SFC Rest API"
+    },
+    "basePath": "/api/nslcm/v1",
+    "paths": {
+        "/ns/sfcs": {
+            "post": {
+                "tags": [
+                    "sfc"
+                ],
+                "summary": "sfc create",
+                "description": "",
+                "operationId": "create_sfc",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/SfcPostRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "",
+                        "schema": {
+                            "$ref": "#/definitions/SfcPostResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/ns/sfcs/{sfcInstId}": {
+            "get": {
+                "tags": [
+                    "sfc"
+                ],
+                "summary": "query the specified sfc info",
+                "description": "",
+                "operationId": "query_sfc",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "sfcInstId",
+                        "in": "path",
+                        "description": "sfc instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/SfcInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the sfc instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "sfc"
+                ],
+                "summary": "delete sfc",
+                "description": "",
+                "operationId": "delete_sfc",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "sfcInstId",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/DeleteResponse"
+                        }
+                    },
+                    "404": {
+                        "description": "the sfc instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        
+        "SfcPostRequest": {
+            "type": "object",
+            "properties": {
+                "jobId": {
+                    "type": "string"
+                },
+                "nsInstanceId": {
+                    "type": "string"
+                },
+                "sapData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "vnfInstanceData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForNs": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForVnf": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "sdnControllerId": {
+                    "type": "string"
+                },
+                "context": {
+                    "type": "string"
+                },
+                "fpindex": {
+                    "type": "string"
+                }
+            }
+        },
+        "SfcPostResponse": {
+            "type": "object",
+            "properties": {
+                "sfcInstId": {
+                    "type": "string"
+                },
+                "jobId": {
+                    "type": "string"
+                }
+            }
+        },
+        "VlInfo": {
+            "type": "object",
+            "properties": {
+                "vlId": {
+                    "type": "string"
+                },
+                "vlName": {
+                    "type": "string"
+                },
+                "vlStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        "VnfInfo": {
+            "type": "object",
+            "properties": {
+                "vnfInstId": {
+                    "type": "string"
+                },
+                "vnfName": {
+                    "type": "string"
+                },
+                "vnfStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        
+        "DeleteResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                }
+            }
+        },        
+        "SfcInfo": {
+            "type": "object",
+            "properties": {
+                "sfcInstId": {
+                    "type": "string"
+                },
+                "sfcName": {
+                    "type": "string"
+                },
+                "sfcStatus": {
+                    "type": "string"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lcm/swagger/vfc.vllcm.swagger.json b/lcm/swagger/vfc.vllcm.swagger.json
new file mode 100644 (file)
index 0000000..1b5241a
--- /dev/null
@@ -0,0 +1,238 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "version": "1.0.0",
+        "title": "ONAP VFC Service Internal Rest API"
+    },
+    "basePath": "/api/nslcm/v1",
+    "paths": {
+        "/ns/vls": {
+            "post": {
+                "tags": [
+                    "vl"
+                ],
+                "summary": "vl create",
+                "description": "",
+                "operationId": "create_vl",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "instantiate request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/VlPostRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "",
+                        "schema": {
+                            "$ref": "#/definitions/VlPostResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/ns/vls/{vlId}": {
+            "get": {
+                "tags": [
+                    "vl"
+                ],
+                "summary": "query the specified vl info",
+                "description": "",
+                "operationId": "query_vl",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "vlId",
+                        "in": "path",
+                        "description": "vl instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/VlInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the vl instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "vl"
+                ],
+                "summary": "delete vl",
+                "description": "",
+                "operationId": "delete_vl",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "vlId",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/DeleteVlResponse"
+                        }
+                    },
+                    "404": {
+                        "description": "the vl instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "VlPostRequest": {
+            "type": "object",
+            "properties": {
+                "jobId": {
+                    "type": "string"
+                },
+                "nsInstanceId": {
+                    "type": "string"
+                },
+                "flavourId": {
+                    "type": "string"
+                },
+                "sapData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "pnfInfo": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "vnfInstanceData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "nestedNsInstanceId": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "locationConstraints": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForNs": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForVnf": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "extNSVirtualLink": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "context": {
+                    "type": "string"
+                },
+                "vlIndex": {
+                    "type": "string"
+                }
+            }
+        },
+        "VlPostResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                },
+                "vlId": {
+                    "type": "string"
+                }
+            }
+        },
+        "VlInfo": {
+            "type": "object",
+            "properties": {
+                "vlId": {
+                    "type": "string"
+                },
+                "vlName": {
+                    "type": "string"
+                },
+                "vlStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        "DeleteVlResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lcm/swagger/vfc.vnflcm.swagger.json b/lcm/swagger/vfc.vnflcm.swagger.json
new file mode 100644 (file)
index 0000000..3fbcb60
--- /dev/null
@@ -0,0 +1,232 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "version": "1.0.0",
+        "title": "ONAP VFC Service Internal Rest API"
+    },
+    "basePath": "/api/nslcm/v1",
+    "paths": {
+        "/ns/vnfs": {
+            "post": {
+                "tags": [
+                    "vnf"
+                ],
+                "summary": "vnf create",
+                "description": "",
+                "operationId": "create_vnf",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "instantiate request param",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/VnfPostRequest"
+                        }
+                    }
+                ],
+                "responses": {
+                    "201": {
+                        "description": "",
+                        "schema": {
+                            "$ref": "#/definitions/VnfPostResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/ns/vnfs/{vnfInstId}": {
+            "get": {
+                "tags": [
+                    "vnf"
+                ],
+                "summary": "query the specified vnf info",
+                "description": "",
+                "operationId": "query_vnf",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "vnfInstId",
+                        "in": "path",
+                        "description": "vnf instance id",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/VnfInfo"
+                        }
+                    },
+                    "404": {
+                        "description": "the vnf instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "vnf"
+                ],
+                "summary": "delete vnf",
+                "description": "",
+                "operationId": "delete_vnf",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "required": true,
+                        "type": "string",
+                        "description": "",
+                        "name": "vnfInstId",
+                        "in": "path"
+                    }
+                ],
+                "responses": {
+                    "204": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/DeleteResponse"
+                        }
+                    },
+                    "404": {
+                        "description": "the vl instance id is wrong"
+                    },
+                    "500": {
+                        "description": "the url is invalid"
+                    }
+                }
+            }
+        }
+    },
+    "definitions": {
+        "VnfPostRequest": {
+            "type": "object",
+            "properties": {
+                "jobId": {
+                    "type": "string"
+                },
+                "nsInstanceId": {
+                    "type": "string"
+                },
+                "flavourId": {
+                    "type": "string"
+                },
+                "sapData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "pnfInfo": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "vnfInstanceData": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "nestedNsInstanceId": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "locationConstraints": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForNs": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "additionalParamForVnf": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "extNSVirtualLink": {
+                    "type": "array",
+                    "items": {
+                        "type": "object"
+                    }
+                },
+                "context": {
+                    "type": "string"
+                },
+                "vnfIndex": {
+                    "type": "string"
+                }
+            }
+        },
+        "VnfPostResponse": {
+            "type": "object",
+            "properties": {
+                "vnfInstId": {
+                    "type": "string"
+                },
+                "jobId": {
+                    "type": "string"
+                }
+            }
+        },
+
+        "VnfInfo": {
+            "type": "object",
+            "properties": {
+                "vnfInstId": {
+                    "type": "string"
+                },
+                "vnfName": {
+                    "type": "string"
+                },
+                "vnfStatus": {
+                    "type": "string"
+                }
+            }
+        },
+        "DeleteResponse": {
+            "type": "object",
+            "properties": {
+                "result": {
+                    "type": "integer",
+                    "enum": [
+                        0,
+                        1
+                    ]
+                },
+                "detail": {
+                    "type": "string"
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lcm/swagger/views.py b/lcm/swagger/views.py
new file mode 100644 (file)
index 0000000..8386bf0
--- /dev/null
@@ -0,0 +1,73 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import json
+import logging
+import os
+import traceback
+
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.views import APIView
+
+
+logger = logging.getLogger(__name__)
+
+
+class SwaggerJsonView(APIView):
+
+    def get(self, request):
+
+        json_file = os.path.join(os.path.dirname(__file__), 'vfc.nslcm.swagger.json')
+        f = open(json_file)
+        json_data = json.JSONDecoder().decode(f.read())
+        f.close()
+
+        json_file = os.path.join(os.path.dirname(__file__), 'vfc.vnflcm.swagger.json')
+        f = open(json_file)
+        json_data_temp = json.JSONDecoder().decode(f.read())
+        f.close()
+
+        json_data["paths"].update(json_data_temp["paths"])
+        json_data["definitions"].update(json_data_temp["definitions"])
+
+        json_file = os.path.join(os.path.dirname(__file__), 'vfc.vllcm.swagger.json')
+        f = open(json_file)
+        json_data_temp = json.JSONDecoder().decode(f.read())
+        f.close()
+
+        json_data["paths"].update(json_data_temp["paths"])
+        json_data["definitions"].update(json_data_temp["definitions"])
+
+
+        json_file = os.path.join(os.path.dirname(__file__), 'vfc.sfclcm.swagger.json')
+        f = open(json_file)
+        json_data_temp = json.JSONDecoder().decode(f.read())
+        f.close()
+
+        json_data["paths"].update(json_data_temp["paths"])
+        json_data["definitions"].update(json_data_temp["definitions"])
+
+
+        json_file = os.path.join(os.path.dirname(__file__), 'vfc.others.swagger.json')
+        f = open(json_file)
+        json_data_temp = json.JSONDecoder().decode(f.read())
+        f.close()
+
+        json_data["paths"].update(json_data_temp["paths"])
+        json_data["definitions"].update(json_data_temp["definitions"])
+
+        return Response(json_data)
+
+    
+
index b033351..5e64726 100644 (file)
@@ -25,6 +25,7 @@ urlpatterns = [
     url(r'^', include('lcm.ns.urls')),
     url(r'^', include('lcm.jobs.urls')),
     url(r'^', include('lcm.workflows.urls')),
+    url(r'^', include('lcm.swagger.urls')),
 ]
 
 # regist to MSB when startup
diff --git a/lcm/workflows/build_in.py b/lcm/workflows/build_in.py
new file mode 100644 (file)
index 0000000..3d06984
--- /dev/null
@@ -0,0 +1,255 @@
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import logging
+import traceback
+from threading import Thread
+import time
+
+from lcm.pub.utils.syscomm import fun_name
+from lcm.pub.utils.values import ignore_case_get
+from lcm.pub.utils import restcall
+from lcm.pub.exceptions import NSLCMException
+
+logger = logging.getLogger(__name__)
+
+RESULT_OK, RESULT_NG = "0", "1"
+JOB_ERROR = 255
+
+g_jobs_status = {}
+
+"""
+format of input_data
+{
+    "jobId": uuid of job, 
+    "nsInstanceId": id of ns instance,
+    "object_context": json format of nsd,
+    "object_additionalParamForNs": json format of additional parameters for ns,
+    "object_additionalParamForVnf": json format of additional parameters for vnf,
+    "vlCount": int type of VL count,
+    "vnfCount: int type of VNF count,
+    "sfcCount": int type of SFC count, 
+    "sdnControllerId": uuid of SDN controller
+}
+"""
+def run_ns_instantiate(input_data):
+    logger.debug("Enter %s, input_data is %s", fun_name(), input_data)
+    job_id = ignore_case_get(input_data, "jobId")
+    ns_inst_id = ignore_case_get(input_data, "nsInstanceId")
+    nsd_json = ignore_case_get(input_data, "object_context")
+    ns_param_json = ignore_case_get(input_data, "object_additionalParamForNs")
+    vnf_param_json = ignore_case_get(input_data, "object_additionalParamForVnf")
+    vl_count = ignore_case_get(input_data, "vlCount")
+    vnf_count = ignore_case_get(input_data, "vnfCount")
+    sfc_count = ignore_case_get(input_data, "sfcCount")
+    sdnc_id = ignore_case_get(input_data, "sdnControllerId")
+    g_jobs_status[job_id] = [1 for i in range(vnf_count)]
+    try:
+        update_job(job_id, 10, "0", "Start to create VL")
+        for i in range(vl_count):
+            create_vl(ns_inst_id, i + 1, nsd_json, ns_param_json)
+
+        update_job(job_id, 30, "0", "Start to create VNF")
+        jobs = [create_vnf(ns_inst_id, i + 1, vnf_param_json) for i in range(vnf_count)] 
+        wait_until_jobs_done(job_id, jobs)
+
+        [confirm_vnf_status(inst_id) for inst_id, _, _ in jobs]
+
+        update_job(job_id, 70, "0", "Start to create SFC")
+        jobs = [create_sfc(ns_inst_id, i + 1, nsd_json, sdnc_id) for i in range(sfc_count)] 
+        wait_until_jobs_done(job_id, jobs)
+
+        [confirm_sfc_status(inst_id) for inst_id, _, _ in jobs]
+
+        update_job(job_id, 90, "0", "Start to post deal")
+        post_deal(ns_inst_id, "true")
+
+        update_job(job_id, 100, "0", "Create NS successfully.")
+    except NSLCMException as e:
+        logger.error("Failded to Create NS: %s", e.message)
+        update_job(job_id, JOB_ERROR, "255", "Failded to Create NS.")
+        post_deal(ns_inst_id, "false")
+    except:
+        logger.error(traceback.format_exc())
+        update_job(job_id, JOB_ERROR, "255", "Failded to Create NS.")
+        post_deal(ns_inst_id, "false")
+    finally:
+        g_jobs_status.pop(job_id)
+
+
+def create_vl(ns_inst_id, vl_index, nsd, ns_param):
+    uri = "api/nslcm/v1/ns/vls"
+    data = json.JSONEncoder().encode({
+        "nsInstanceId": ns_inst_id,
+        "vlIndex": vl_index,
+        "context": nsd,
+        "additionalParamForNs": ns_param
+    })
+
+    ret = restcall.req_by_msb(uri, "POST", data)
+    if ret[0] != 0:
+        logger.error("Failed to call create_vl(%s): %s", vl_index, ret[1])
+        raise NSLCMException("Failed to call create_vl(index is %s)" % vl_index)
+
+    result = str(ret[1]["result"])
+    detail = ret[1]["detail"]
+    vl_id = ret[1]["vlId"]
+    if result != RESULT_OK:
+        logger.error("Failed to create VL(%s): %s", vl_id, detail)
+        raise NSLCMException("Failed to create VL(%s)" % vl_id)
+
+    logger.debug("Create VL(%s) successfully.", vl_id)
+
+def create_vnf(ns_inst_id, vnf_index, nf_param):
+    uri = "/ns/vnfs"
+    data = json.JSONEncoder().encode({
+        "nsInstanceId": ns_inst_id,
+        "vnfIndex": vnf_index,
+        "additionalParamForVnf": nf_param
+    })
+
+    ret = restcall.req_by_msb(uri, "POST", data)
+    if ret[0] != 0:
+        logger.error("Failed to call create_vnf(%s): %s", vnf_index, ret[1])
+        raise NSLCMException("Failed to call create_vnf(index is %s)" % vnf_index)
+
+    vnf_inst_id = ret[1]["vnfInstId"]
+    job_id = ret[1]["jobId"]
+    logger.debug("Create VNF(%s) started.", vnf_inst_id)
+    return vnf_inst_id, job_id, vnf_index - 1
+
+def create_sfc(ns_inst_id, fp_index, nsd_json, sdnc_id):
+    uri = "/ns/sfcs"
+    data = json.JSONEncoder().encode({
+        "nsInstanceId": ns_inst_id,
+        "context": nsd_json,
+        "fpindex": fp_index,
+        "sdnControllerId": sdnc_id
+    })
+
+    ret = restcall.req_by_msb(uri, "POST", data)
+    if ret[0] != 0:
+        logger.error("Failed to call create_sfc(%s): %s", fp_index, ret[1])
+        raise NSLCMException("Failed to call create_sfc(index is %s)" % fp_index)
+
+    sfc_inst_id = ret[1]["sfcInstId"]
+    job_id = ret[1]["jobId"]
+    logger.debug("Create SFC(%s) started.", sfc_inst_id)
+    return sfc_inst_id, job_id, fp_index - 1
+
+def post_deal(ns_inst_id, status):
+    uri = "/ns/{nsInstanceId}/postdeal".format(nsInstanceId=ns_inst_id) 
+    data = json.JSONEncoder().encode({
+        "status": status
+    })
+
+    ret = restcall.req_by_msb(uri, "POST", data)
+    if ret[0] != 0:
+        logger.error("Failed to call post_deal(%s): %s", ns_inst_id, ret[1])
+    logger.debug("Call post_deal(%s) successfully.", ns_inst_id)
+
+def update_job(job_id, progress, errcode, desc):
+    uri = "api/nslcm/v1/jobs/{jobId}".format(jobId=job_id)
+    data = json.JSONEncoder().encode({
+        "progress": progress,
+        "errcode": errcode,
+        "desc": desc
+    })
+    restcall.req_by_msb(uri, "POST", data)  
+
+class JobWaitThread(Thread):
+    """
+    Job Wait 
+    """
+
+    def __init__(self, inst_id, job_id, index):
+        Thread.__init__(self)
+        self.inst_id = inst_id
+        self.job_id = job_id
+        self.index = index
+        self.retry_count = 60
+        self.interval_second = 3
+
+    def run(self):
+        count = 0
+        response_id, new_response_id = 0, 0
+        job_end_normal, job_timeout = False, True
+        while count < self.retry_count:
+            count = count + 1
+            time.sleep(self.interval_second)
+            uri = "/api/nslcm/v1/jobs/%s?responseId=%s" % (self.job_id, response_id)
+            ret = restcall.req_by_msb(uri, "GET")
+            if ret[0] != 0:
+                logger.error("Failed to query job: %s:%s", ret[2], ret[1])
+                continue
+            job_result = json.JSONDecoder().decode(ret[1])
+            if "responseDescriptor" not in job_result:
+                logger.error("Job(%s) does not exist.", self.job_id)
+                continue
+            progress = job_result["responseDescriptor"]["progress"]
+            new_response_id = job_result["responseDescriptor"]["responseId"]
+            job_desc = job_result["responseDescriptor"]["statusDescription"]
+            if new_response_id != response_id:
+                logger.debug("%s:%s:%s", progress, new_response_id, job_desc)
+                response_id = new_response_id
+                count = 0
+            if progress == JOB_ERROR:
+                job_timeout = False
+                logger.error("Job(%s) failed: %s", self.job_id, job_desc)
+                break
+            elif progress == 100:
+                job_end_normal, job_timeout = True, False
+                logger.info("Job(%s) ended normally", self.job_id)
+                break
+        if job_timeout:
+            logger.error("Job(%s) timeout", self.job_id)
+        if self.job_id in g_jobs_status:
+            if job_end_normal:
+                g_jobs_status[self.job_id][self.index] = 0
+
+def wait_until_jobs_done(g_job_id, jobs):
+    job_threads = []
+    for inst_id, job_id, index in jobs:
+        job_threads.append(JobWaitThread(inst_id, job_id, index))
+    for t in job_threads:
+        t.start()
+    for t in job_threads:
+        t.join()
+    if g_job_id in g_jobs_status:
+        if sum(g_jobs_status[g_job_id]) > 0:
+            raise NSLCMException("Some jobs failed!")
+
+def confirm_vnf_status(vnf_inst_id):
+    uri = "api/nslcm/v1/ns/vnfs/{vnfInstId}".format(vnfInstId=vnf_inst_id)
+    ret = restcall.req_by_msb(uri, "GET")
+    if ret[0] != 0:
+        raise NSLCMException("Failed to call get_vnf(%s)" % vnf_inst_id)
+    vnf_status = ret[1]["vnfStatus"]
+    if vnf_status != "active":
+        raise NSLCMException("Status of VNF(%s) is not active" % vnf_inst_id)
+
+def confirm_sfc_status(sfc_inst_id):
+    uri = "api/nslcm/v1/ns/sfcs/{sfcInstId}".format(sfcInstId=sfc_inst_id)
+    ret = restcall.req_by_msb(uri, "GET")
+    if ret[0] != 0:
+        raise NSLCMException("Failed to call get_sfc(%s)" % sfc_inst_id)
+    sfc_status = ret[1]["sfcStatus"]
+    if sfc_status != "active":
+        raise NSLCMException("Status of SFC(%s) is not active" % sfc_inst_id)
+
+
+
+
+
+      
+