Change naming and veriy test-scheduler function
[bottlenecks.git] / test-scheduler / server / src / rest / router.py
similarity index 97%
rename from testing-scheduler/server/src/rest/router.py
rename to test-scheduler/server/src/rest/router.py
index b9cbd92..1ceeedd 100644 (file)
-##############################################################################\r
-# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are made available under the terms of the Apache License, Version 2.0\r
-# which accompanies this distribution, and is available at\r
-# http://www.apache.org/licenses/LICENSE-2.0\r
-##############################################################################\r
-\r
-from flask import Flask\r
-from flask import jsonify\r
-from flask import request\r
-from flask_cors import CORS\r
-import os\r
-import json\r
-import time\r
-import pyaml\r
-import yaml\r
-import traceback\r
-\r
-import src.test_parser as test_parser\r
-\r
-\r
-BASE_DIR = os.path.abspath(os.path.dirname(__file__))\r
-TESTSUITE_DIR = os.path.join(BASE_DIR, "..", "..", "test", "test_case")\r
-SERVICE_DIR = os.path.join(BASE_DIR, "..", "env", "service")\r
-CONTEXT_FILE_DIR = os.path.join(BASE_DIR, "..", "env", "context",\r
-                                "context.yaml")\r
-app = Flask(__name__)\r
-CORS(app)\r
-\r
-\r
-###############\r
-# 1. EXECUTE API\r
-###########################################################################\r
-@app.route("/")\r
-def hello():\r
-    return "Hello, World! This is a greet from parser." + SERVICE_DIR\r
-\r
-\r
-@app.route("/execute/testcase", methods=['POST'])\r
-def runTestcase():\r
-    suiteName = request.values.get('suiteName')\r
-    caseName = request.values.get('caseName')\r
-    try:\r
-        casePath = os.path.join(TESTSUITE_DIR, suiteName, caseName)\r
-        if os.path.exists(casePath):\r
-            workflowId = test_parser.parse(casePath)\r
-            if workflowId is None or workflowId == '':\r
-                return jsonify({"code": 500, "error": "Server Error."})\r
-            return jsonify({"code": 200, "result": {"workflowId": workflowId}})\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such test case:  %s" %\r
-                           (os.path.join(suiteName, caseName))})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-\r
-@app.route("/story-content")\r
-def getStoryContent():\r
-    try:\r
-        story_name = request.args['story']\r
-        service_name = request.args['service']\r
-        storyFileDir = os.path.join("/tmp", "generate_workflow.json")\r
-        with open(storyFileDir, "r") as f:\r
-            storyContent = f.read()\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    result = {"code": 200, "result":\r
-              {"service": service_name, "story": story_name,\r
-               "content": storyContent}}\r
-    return jsonify(result)\r
-\r
-\r
-###############\r
-# 2. TESTCASE CRUD\r
-###########################################################################\r
-@app.route("/testsuite/list")\r
-def getAllSuite():\r
-    res = []\r
-    id = 1\r
-    try:\r
-        for fileName in os.listdir(TESTSUITE_DIR):\r
-            suiteInfo = {}\r
-            suiteInfo["id"] = id\r
-            suiteInfo["testsuite"] = fileName\r
-            res.append(suiteInfo)\r
-            id = id + 1\r
-    except BaseException, e:\r
-        print e\r
-        app.logger.error(traceback.format_exc())\r
-        return jsonify({"code": 500, "error": "Server error"})\r
-\r
-    return jsonify({"code": 200, "result": res})\r
-\r
-\r
-@app.route("/testsuite/content")\r
-def getSuiteContent():\r
-    res = []\r
-    id = 1\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
-        if os.path.exists(exSuitePath):\r
-            for fileName in os.listdir(exSuitePath):\r
-                tcInfo = {}\r
-                tcInfo["id"] = id\r
-                tcInfo["testcase"] = fileName\r
-                res.append(tcInfo)\r
-                id = id + 1\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such test suite!"})\r
-    except BaseException, e:\r
-        print e\r
-        app.logger.error(traceback.format_exc())\r
-        return jsonify({"code": 500, "error": "Server error"})\r
-\r
-    return jsonify({"code": 200, "result": res})\r
-\r
-\r
-@app.route("/testcase/content")\r
-def getTCContent():\r
-    res = ""\r
-    editorRes = ""\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        caseName = request.values.get("caseName")\r
-        casePath = os.path.join(suiteName, caseName)\r
-        casePath = os.path.join(TESTSUITE_DIR, casePath)\r
-        if os.path.exists(casePath):\r
-            with open(casePath, "r") as f:\r
-                fileContent = f.read()\r
-            res = fileContent\r
-            editorRes = test_parser.getWebTestcase(yaml.load(res))\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such file!"})\r
-    except BaseException, e:\r
-        print e\r
-        app.logger.error(traceback.format_exc())\r
-        return jsonify({"code": 500, "error": "Server error"})\r
-\r
-    return jsonify({"code": 200, "result":\r
-                    {"content": res, "editorContent": editorRes}})\r
-\r
-\r
-@app.route("/testsuite/new", methods=['POST'])\r
-def addNewSuite():\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        for fileName in os.listdir(TESTSUITE_DIR):\r
-            if fileName == suiteName:\r
-                return jsonify({"code": 300,\r
-                                "error": "testsuite already exists!"})\r
-        testSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
-        os.mkdir(testSuitePath)\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    return jsonify({"code": 200, "result": "ok"})\r
-\r
-\r
-@app.route("/testsuite/delete", methods=['POST'])\r
-def deleteSuite():\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        for fileName in os.listdir(TESTSUITE_DIR):\r
-            if fileName == suiteName:\r
-                testSuitePath = os.path.join(TESTSUITE_DIR, fileName)\r
-                del_file(testSuitePath)\r
-                os.rmdir(testSuitePath)\r
-                return jsonify({"code": 200, "result": "ok"})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    return jsonify({"code": 300, "error": "no such testsuite!"})\r
-\r
-\r
-def del_file(path):\r
-    for i in os.listdir(path):\r
-        path_file = os.path.join(path, i)\r
-        if os.path.isfile(path_file):\r
-            os.remove(path_file)\r
-        else:\r
-            del_file(path_file)\r
-\r
-\r
-@app.route("/testcase/new", methods=['POST'])\r
-def createTestcase():\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        caseName = request.values.get("caseName")\r
-        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
-        if os.path.exists(exSuitePath):\r
-            for fileName in os.listdir(exSuitePath):\r
-                if fileName == caseName:\r
-                    return jsonify({"code": 301,\r
-                                    "error": "testcase already exists!"})\r
-            casePath = os.path.join(exSuitePath, caseName)\r
-            with open(casePath, "w") as f:\r
-                # the next line is a placeholder.\r
-                print f\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such test suite!"})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    return jsonify({"code": 200, "result": "ok"})\r
-\r
-\r
-@app.route("/testcase/delete", methods=['POST'])\r
-def deleteTestcase():\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        caseName = request.values.get("caseName")\r
-        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)\r
-        if os.path.exists(exSuitePath):\r
-            for fileName in os.listdir(exSuitePath):\r
-                if fileName == caseName:\r
-                    casePath = os.path.join(exSuitePath, caseName)\r
-                    os.remove(casePath)\r
-                    return jsonify({"code": 200, "result": "ok"})\r
-            return jsonify({"code": 301, "error": "no such test case!"})\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such test suite!"})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-\r
-@app.route("/testcase/save", methods=["POST"])\r
-def saveTCContent():\r
-    try:\r
-        suiteName = request.values.get("suiteName")\r
-        caseName = request.values.get("caseName")\r
-        stepList = json.loads(request.values.get("stepList"))\r
-        subflowList = json.loads(request.values.get("subflowList"))\r
-        mainOrdersList = json.loads(request.values.get("mainOrdersList"))\r
-        jsonObj = {"stepList": stepList, "subflowList": subflowList,\r
-                   "mainOrdersList": mainOrdersList}\r
-        parseData = test_parser.parseWebTestcase(jsonObj)\r
-\r
-        casePath = os.path.join(suiteName, caseName)\r
-        casePath = os.path.join(TESTSUITE_DIR, casePath)\r
-        if os.path.exists(casePath):\r
-            with open(casePath, "w") as f:\r
-                pyaml.dump(parseData, f, safe=True)\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such file!"})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    return jsonify({"code": 200, "result": "save success"})\r
-\r
-\r
-###############\r
-# 3.1 API FOR SERVICE\r
-############################################################\r
-@app.route("/service/list")\r
-def getAllServices():\r
-    res = []\r
-    try:\r
-        for fileName in os.listdir(SERVICE_DIR):\r
-            serviceName = os.path.splitext(fileName)[0]\r
-            res.append(serviceName)\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    return jsonify({"code": 200, "result": res})\r
-\r
-\r
-@app.route("/service/content")\r
-def getServiceContent():\r
-    res = {}\r
-    try:\r
-        serviceName = request.values.get("serviceName")\r
-        for fileName in os.listdir(SERVICE_DIR):\r
-            if serviceName == os.path.splitext(fileName)[0]:\r
-                res["actions"] = []\r
-                filePath = os.path.join(SERVICE_DIR, fileName)\r
-                with open(filePath, "r") as f:\r
-                    content = yaml.load(f)\r
-                    apisArr = content[serviceName]['apis']\r
-                    for i in range(len(apisArr)):\r
-                        apisArr[i].pop("method")\r
-                        apisArr[i].pop("baseuri")\r
-                    res["actions"] = apisArr\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    if res == {}:\r
-        return jsonify({"code": 300, "error": "no such service!"})\r
-\r
-    return jsonify({"code": 200, "result": res})\r
-\r
-\r
-def paramTransform(paramDict):\r
-    res = []\r
-    for (key, value) in paramDict.items():\r
-        paramJson = {}\r
-        paramJson["name"] = key\r
-        paramJson["description"] = value["help"]\r
-        if "params" in value:\r
-            paramJson["params"] = paramTransform(value["params"])\r
-        res.append(paramJson)\r
-    return res\r
-\r
-\r
-@app.route("/service/action_response")\r
-def actionResponse():\r
-    res = {}\r
-    try:\r
-        serviceName = request.values.get("serviceName")\r
-        actionName = request.values.get("actionName")\r
-        for fileName in os.listdir(SERVICE_DIR):\r
-            if serviceName == os.path.splitext(fileName)[0]:\r
-                res["responseParams"] = []\r
-                filePath = os.path.join(SERVICE_DIR, fileName)\r
-                with open(filePath, "r") as f:\r
-                    content = yaml.load(f)\r
-                    apisArr = content[serviceName]['apis']\r
-                for i in range(len(apisArr)):\r
-                    if actionName == apisArr[i]['name'] and (\r
-                       "response" in apisArr[i]):\r
-                        res["responseParams"] = apisArr[i]["response"]\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-    if res == {}:\r
-        return jsonify({"code": 300, "error": "no such service!"})\r
-    return jsonify({"code": 200, "result": res})\r
-\r
-\r
-###############\r
-# 3.2 API FOR ENVIRONMENT SERVICE AND CONTEXT\r
-###########################################################################\r
-@app.route('/env/getAllServices')\r
-def getAllService():\r
-    res = []\r
-    id = 1\r
-    try:\r
-        for fileName in os.listdir(SERVICE_DIR):\r
-            item = {}\r
-            item['id'] = id\r
-            item['name'] = os.path.splitext(fileName)[0]\r
-            filePath = os.path.join(SERVICE_DIR, fileName)\r
-            filemt = time.localtime(os.stat(filePath).st_mtime)\r
-            item['time'] = time.strftime("%Y-%m-%d", filemt)\r
-            res.append(item)\r
-            id = id + 1\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-    return jsonify({"code": 200, "result": res})\r
-\r
-\r
-@app.route('/env/getService')\r
-def getService():\r
-    try:\r
-        serviceName = request.values.get('serviceName')\r
-        serviceFile = serviceName + '.yaml'\r
-        servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
-        if os.path.exists(servicePath):\r
-            with open(servicePath, "r") as f:\r
-                serviceDict = yaml.load(f)\r
-                serviceDict = serviceDict[serviceName]\r
-            return jsonify({"code": 200, "result": serviceDict})\r
-        else:\r
-            return jsonify({"code": 300, "error": "no such service!"})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-\r
-@app.route('/env/createService', methods=['POST'])\r
-def createService():\r
-    try:\r
-        name = str(request.values.get('name'))\r
-        ip = str(request.values.get('ip'))\r
-        port = int(request.values.get('port'))\r
-        apis = json.loads(request.values.get('apis'))\r
-        service = {\r
-            name: {\r
-                'ip': ip,\r
-                'port': port,\r
-                'apis': apis\r
-            }\r
-        }\r
-        serviceJson = json.dumps(service, indent=True)\r
-        print serviceJson\r
-        app.logger.debug(service)\r
-\r
-        serviceFile = name + '.yaml'\r
-        servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
-        with open(servicePath, 'w') as f:\r
-            pyaml.dump(service, f, safe=True)\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-    return jsonify({"code": 200, "result": "create success!"})\r
-\r
-\r
-@app.route('/env/editService', methods=['POST'])\r
-def editService():\r
-    try:\r
-        oldName = str(request.values.get('oldName'))\r
-        name = str(request.values.get('newName'))\r
-        ip = str(request.values.get('ip'))\r
-        port = int(request.values.get('port'))\r
-        apis = json.loads(request.values.get('apis'))\r
-        app.logger.debug(apis)\r
-        service = {\r
-            name: {\r
-                'ip': ip,\r
-                'port': port,\r
-                'apis': apis\r
-            }\r
-        }\r
-        serviceJson = json.dumps(service, indent=True)\r
-        print serviceJson\r
-        app.logger.debug(service)\r
-\r
-        for fileName in os.listdir(SERVICE_DIR):\r
-            serviceName = os.path.splitext(fileName)[0]\r
-            if serviceName == oldName:\r
-                filePath = os.path.join(SERVICE_DIR, fileName)\r
-                os.remove(filePath)\r
-\r
-        serviceFile = name + '.yaml'\r
-        servicePath = os.path.join(SERVICE_DIR, serviceFile)\r
-        with open(servicePath, 'w') as f:\r
-            pyaml.dump(service, f, safe=True)\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-    return jsonify({"code": 200, "result": "edit success!"})\r
-\r
-\r
-@app.route('/env/deleteService', methods=['POST'])\r
-def deleteService():\r
-    try:\r
-        name = str(request.values.get('serviceName'))\r
-\r
-        for fileName in os.listdir(SERVICE_DIR):\r
-            serviceName = os.path.splitext(fileName)[0]\r
-            if serviceName == name:\r
-                filePath = os.path.join(SERVICE_DIR, fileName)\r
-                os.remove(filePath)\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-    return jsonify({"code": 200, "result": "delete success!"})\r
-\r
-\r
-@app.route('/env/getContext')\r
-def getContext():\r
-    try:\r
-        with open(CONTEXT_FILE_DIR, "r") as f:\r
-            fileContent = f.read()\r
-        res = fileContent\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-    return jsonify({"code": 200, "result": {"context": res}})\r
-\r
-\r
-@app.route('/env/editContext', methods=['POST'])\r
-def editContext():\r
-    try:\r
-        context = request.values.get("context")\r
-        test = yaml.load(context)\r
-        print test\r
-        with open(CONTEXT_FILE_DIR, "w") as f:\r
-            f.write(context)\r
-    except yaml.constructor.ConstructorError, e:\r
-        app.logger.error(traceback.format_exc())\r
-        return jsonify({"code": 500, "error":\r
-                        "context content error: not a .yaml file!"})\r
-    except BaseException, e:\r
-        return returnServerError(e)\r
-\r
-    return jsonify({"code": 200, "result": "edit context success!"})\r
-###########################################################################\r
-\r
-\r
-def returnServerError(e, msg="Server Error"):\r
-    print e\r
-    app.logger.error(traceback.format_exc())\r
-    return jsonify({"code": 500, "error": msg})\r
-\r
-\r
-if __name__ == "__main__":\r
-    app.run(host='0.0.0.0', port=5310)\r
+##############################################################################
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from flask import Flask
+from flask import jsonify
+from flask import request
+from flask_cors import CORS
+import os
+import json
+import time
+import pyaml
+import yaml
+import traceback
+
+import src.test_parser as test_parser
+
+
+BASE_DIR = os.path.abspath(os.path.dirname(__file__))
+TESTSUITE_DIR = os.path.join(BASE_DIR, "..", "..", "test", "test_case")
+SERVICE_DIR = os.path.join(BASE_DIR, "..", "env", "service")
+CONTEXT_FILE_DIR = os.path.join(BASE_DIR, "..", "env", "context",
+                                "context.yaml")
+app = Flask(__name__)
+CORS(app)
+
+
+###############
+# 1. EXECUTE API
+###########################################################################
+@app.route("/")
+def hello():
+    return "Hello, World! This is a greet from parser." + SERVICE_DIR
+
+
+@app.route("/execute/testcase", methods=['POST'])
+def runTestcase():
+    suiteName = request.values.get('suiteName')
+    caseName = request.values.get('caseName')
+    try:
+        casePath = os.path.join(TESTSUITE_DIR, suiteName, caseName)
+        if os.path.exists(casePath):
+            workflowId = test_parser.parse(casePath)
+            if workflowId is None or workflowId == '':
+                return jsonify({"code": 500, "error": "Server Error."})
+            return jsonify({"code": 200, "result": {"workflowId": workflowId}})
+        else:
+            return jsonify({"code": 300, "error": "no such test case:  %s" %
+                           (os.path.join(suiteName, caseName))})
+    except BaseException, e:
+        return returnServerError(e)
+
+
+@app.route("/story-content")
+def getStoryContent():
+    try:
+        story_name = request.args['story']
+        service_name = request.args['service']
+        storyFileDir = os.path.join("/tmp", "generate_workflow.json")
+        with open(storyFileDir, "r") as f:
+            storyContent = f.read()
+    except BaseException, e:
+        return returnServerError(e)
+
+    result = {"code": 200, "result":
+              {"service": service_name, "story": story_name,
+               "content": storyContent}}
+    return jsonify(result)
+
+
+###############
+# 2. TESTCASE CRUD
+###########################################################################
+@app.route("/testsuite/list")
+def getAllSuite():
+    res = []
+    id = 1
+    try:
+        for fileName in os.listdir(TESTSUITE_DIR):
+            suiteInfo = {}
+            suiteInfo["id"] = id
+            suiteInfo["testsuite"] = fileName
+            res.append(suiteInfo)
+            id = id + 1
+    except BaseException, e:
+        print e
+        app.logger.error(traceback.format_exc())
+        return jsonify({"code": 500, "error": "Server error"})
+
+    return jsonify({"code": 200, "result": res})
+
+
+@app.route("/testsuite/content")
+def getSuiteContent():
+    res = []
+    id = 1
+    try:
+        suiteName = request.values.get("suiteName")
+        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)
+        if os.path.exists(exSuitePath):
+            for fileName in os.listdir(exSuitePath):
+                tcInfo = {}
+                tcInfo["id"] = id
+                tcInfo["testcase"] = fileName
+                res.append(tcInfo)
+                id = id + 1
+        else:
+            return jsonify({"code": 300, "error": "no such test suite!"})
+    except BaseException, e:
+        print e
+        app.logger.error(traceback.format_exc())
+        return jsonify({"code": 500, "error": "Server error"})
+
+    return jsonify({"code": 200, "result": res})
+
+
+@app.route("/testcase/content")
+def getTCContent():
+    res = ""
+    editorRes = ""
+    try:
+        suiteName = request.values.get("suiteName")
+        caseName = request.values.get("caseName")
+        casePath = os.path.join(suiteName, caseName)
+        casePath = os.path.join(TESTSUITE_DIR, casePath)
+        if os.path.exists(casePath):
+            with open(casePath, "r") as f:
+                fileContent = f.read()
+            res = fileContent
+            editorRes = test_parser.getWebTestcase(yaml.load(res))
+        else:
+            return jsonify({"code": 300, "error": "no such file!"})
+    except BaseException, e:
+        print e
+        app.logger.error(traceback.format_exc())
+        return jsonify({"code": 500, "error": "Server error"})
+
+    return jsonify({"code": 200, "result":
+                    {"content": res, "editorContent": editorRes}})
+
+
+@app.route("/testsuite/new", methods=['POST'])
+def addNewSuite():
+    try:
+        suiteName = request.values.get("suiteName")
+        for fileName in os.listdir(TESTSUITE_DIR):
+            if fileName == suiteName:
+                return jsonify({"code": 300,
+                                "error": "testsuite already exists!"})
+        testSuitePath = os.path.join(TESTSUITE_DIR, suiteName)
+        os.mkdir(testSuitePath)
+    except BaseException, e:
+        return returnServerError(e)
+
+    return jsonify({"code": 200, "result": "ok"})
+
+
+@app.route("/testsuite/delete", methods=['POST'])
+def deleteSuite():
+    try:
+        suiteName = request.values.get("suiteName")
+        for fileName in os.listdir(TESTSUITE_DIR):
+            if fileName == suiteName:
+                testSuitePath = os.path.join(TESTSUITE_DIR, fileName)
+                del_file(testSuitePath)
+                os.rmdir(testSuitePath)
+                return jsonify({"code": 200, "result": "ok"})
+    except BaseException, e:
+        return returnServerError(e)
+
+    return jsonify({"code": 300, "error": "no such testsuite!"})
+
+
+def del_file(path):
+    for i in os.listdir(path):
+        path_file = os.path.join(path, i)
+        if os.path.isfile(path_file):
+            os.remove(path_file)
+        else:
+            del_file(path_file)
+
+
+@app.route("/testcase/new", methods=['POST'])
+def createTestcase():
+    try:
+        suiteName = request.values.get("suiteName")
+        caseName = request.values.get("caseName")
+        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)
+        if os.path.exists(exSuitePath):
+            for fileName in os.listdir(exSuitePath):
+                if fileName == caseName:
+                    return jsonify({"code": 301,
+                                    "error": "testcase already exists!"})
+            casePath = os.path.join(exSuitePath, caseName)
+            with open(casePath, "w") as f:
+                # the next line is a placeholder.
+                print f
+        else:
+            return jsonify({"code": 300, "error": "no such test suite!"})
+    except BaseException, e:
+        return returnServerError(e)
+
+    return jsonify({"code": 200, "result": "ok"})
+
+
+@app.route("/testcase/delete", methods=['POST'])
+def deleteTestcase():
+    try:
+        suiteName = request.values.get("suiteName")
+        caseName = request.values.get("caseName")
+        exSuitePath = os.path.join(TESTSUITE_DIR, suiteName)
+        if os.path.exists(exSuitePath):
+            for fileName in os.listdir(exSuitePath):
+                if fileName == caseName:
+                    casePath = os.path.join(exSuitePath, caseName)
+                    os.remove(casePath)
+                    return jsonify({"code": 200, "result": "ok"})
+            return jsonify({"code": 301, "error": "no such test case!"})
+        else:
+            return jsonify({"code": 300, "error": "no such test suite!"})
+    except BaseException, e:
+        return returnServerError(e)
+
+
+@app.route("/testcase/save", methods=["POST"])
+def saveTCContent():
+    try:
+        suiteName = request.values.get("suiteName")
+        caseName = request.values.get("caseName")
+        stepList = json.loads(request.values.get("stepList"))
+        subflowList = json.loads(request.values.get("subflowList"))
+        mainOrdersList = json.loads(request.values.get("mainOrdersList"))
+        jsonObj = {"stepList": stepList, "subflowList": subflowList,
+                   "mainOrdersList": mainOrdersList}
+        parseData = test_parser.parseWebTestcase(jsonObj)
+
+        casePath = os.path.join(suiteName, caseName)
+        casePath = os.path.join(TESTSUITE_DIR, casePath)
+        if os.path.exists(casePath):
+            with open(casePath, "w") as f:
+                pyaml.dump(parseData, f, safe=True)
+        else:
+            return jsonify({"code": 300, "error": "no such file!"})
+    except BaseException, e:
+        return returnServerError(e)
+
+    return jsonify({"code": 200, "result": "save success"})
+
+
+###############
+# 3.1 API FOR SERVICE
+############################################################
+@app.route("/service/list")
+def getAllServices():
+    res = []
+    try:
+        for fileName in os.listdir(SERVICE_DIR):
+            serviceName = os.path.splitext(fileName)[0]
+            res.append(serviceName)
+    except BaseException, e:
+        return returnServerError(e)
+
+    return jsonify({"code": 200, "result": res})
+
+
+@app.route("/service/content")
+def getServiceContent():
+    res = {}
+    try:
+        serviceName = request.values.get("serviceName")
+        for fileName in os.listdir(SERVICE_DIR):
+            if serviceName == os.path.splitext(fileName)[0]:
+                res["actions"] = []
+                filePath = os.path.join(SERVICE_DIR, fileName)
+                with open(filePath, "r") as f:
+                    content = yaml.load(f)
+                    apisArr = content[serviceName]['apis']
+                    for i in range(len(apisArr)):
+                        apisArr[i].pop("method")
+                        apisArr[i].pop("baseuri")
+                    res["actions"] = apisArr
+    except BaseException, e:
+        return returnServerError(e)
+
+    if res == {}:
+        return jsonify({"code": 300, "error": "no such service!"})
+
+    return jsonify({"code": 200, "result": res})
+
+
+def paramTransform(paramDict):
+    res = []
+    for (key, value) in paramDict.items():
+        paramJson = {}
+        paramJson["name"] = key
+        paramJson["description"] = value["help"]
+        if "params" in value:
+            paramJson["params"] = paramTransform(value["params"])
+        res.append(paramJson)
+    return res
+
+
+@app.route("/service/action_response")
+def actionResponse():
+    res = {}
+    try:
+        serviceName = request.values.get("serviceName")
+        actionName = request.values.get("actionName")
+        for fileName in os.listdir(SERVICE_DIR):
+            if serviceName == os.path.splitext(fileName)[0]:
+                res["responseParams"] = []
+                filePath = os.path.join(SERVICE_DIR, fileName)
+                with open(filePath, "r") as f:
+                    content = yaml.load(f)
+                    apisArr = content[serviceName]['apis']
+                for i in range(len(apisArr)):
+                    if actionName == apisArr[i]['name'] and (
+                       "response" in apisArr[i]):
+                        res["responseParams"] = apisArr[i]["response"]
+    except BaseException, e:
+        return returnServerError(e)
+    if res == {}:
+        return jsonify({"code": 300, "error": "no such service!"})
+    return jsonify({"code": 200, "result": res})
+
+
+###############
+# 3.2 API FOR ENVIRONMENT SERVICE AND CONTEXT
+###########################################################################
+@app.route('/env/getAllServices')
+def getAllService():
+    res = []
+    id = 1
+    try:
+        for fileName in os.listdir(SERVICE_DIR):
+            item = {}
+            item['id'] = id
+            item['name'] = os.path.splitext(fileName)[0]
+            filePath = os.path.join(SERVICE_DIR, fileName)
+            filemt = time.localtime(os.stat(filePath).st_mtime)
+            item['time'] = time.strftime("%Y-%m-%d", filemt)
+            res.append(item)
+            id = id + 1
+    except BaseException, e:
+        return returnServerError(e)
+    return jsonify({"code": 200, "result": res})
+
+
+@app.route('/env/getService')
+def getService():
+    try:
+        serviceName = request.values.get('serviceName')
+        serviceFile = serviceName + '.yaml'
+        servicePath = os.path.join(SERVICE_DIR, serviceFile)
+        if os.path.exists(servicePath):
+            with open(servicePath, "r") as f:
+                serviceDict = yaml.load(f)
+                serviceDict = serviceDict[serviceName]
+            return jsonify({"code": 200, "result": serviceDict})
+        else:
+            return jsonify({"code": 300, "error": "no such service!"})
+    except BaseException, e:
+        return returnServerError(e)
+
+
+@app.route('/env/createService', methods=['POST'])
+def createService():
+    try:
+        name = str(request.values.get('name'))
+        ip = str(request.values.get('ip'))
+        port = int(request.values.get('port'))
+        apis = json.loads(request.values.get('apis'))
+        service = {
+            name: {
+                'ip': ip,
+                'port': port,
+                'apis': apis
+            }
+        }
+        serviceJson = json.dumps(service, indent=True)
+        print serviceJson
+        app.logger.debug(service)
+
+        serviceFile = name + '.yaml'
+        servicePath = os.path.join(SERVICE_DIR, serviceFile)
+        with open(servicePath, 'w') as f:
+            pyaml.dump(service, f, safe=True)
+    except BaseException, e:
+        return returnServerError(e)
+    return jsonify({"code": 200, "result": "create success!"})
+
+
+@app.route('/env/editService', methods=['POST'])
+def editService():
+    try:
+        oldName = str(request.values.get('oldName'))
+        name = str(request.values.get('newName'))
+        ip = str(request.values.get('ip'))
+        port = int(request.values.get('port'))
+        apis = json.loads(request.values.get('apis'))
+        app.logger.debug(apis)
+        service = {
+            name: {
+                'ip': ip,
+                'port': port,
+                'apis': apis
+            }
+        }
+        serviceJson = json.dumps(service, indent=True)
+        print serviceJson
+        app.logger.debug(service)
+
+        for fileName in os.listdir(SERVICE_DIR):
+            serviceName = os.path.splitext(fileName)[0]
+            if serviceName == oldName:
+                filePath = os.path.join(SERVICE_DIR, fileName)
+                os.remove(filePath)
+
+        serviceFile = name + '.yaml'
+        servicePath = os.path.join(SERVICE_DIR, serviceFile)
+        with open(servicePath, 'w') as f:
+            pyaml.dump(service, f, safe=True)
+    except BaseException, e:
+        return returnServerError(e)
+    return jsonify({"code": 200, "result": "edit success!"})
+
+
+@app.route('/env/deleteService', methods=['POST'])
+def deleteService():
+    try:
+        name = str(request.values.get('serviceName'))
+
+        for fileName in os.listdir(SERVICE_DIR):
+            serviceName = os.path.splitext(fileName)[0]
+            if serviceName == name:
+                filePath = os.path.join(SERVICE_DIR, fileName)
+                os.remove(filePath)
+    except BaseException, e:
+        return returnServerError(e)
+    return jsonify({"code": 200, "result": "delete success!"})
+
+
+@app.route('/env/getContext')
+def getContext():
+    try:
+        with open(CONTEXT_FILE_DIR, "r") as f:
+            fileContent = f.read()
+        res = fileContent
+    except BaseException, e:
+        return returnServerError(e)
+    return jsonify({"code": 200, "result": {"context": res}})
+
+
+@app.route('/env/editContext', methods=['POST'])
+def editContext():
+    try:
+        context = request.values.get("context")
+        test = yaml.load(context)
+        print test
+        with open(CONTEXT_FILE_DIR, "w") as f:
+            f.write(context)
+    except yaml.constructor.ConstructorError, e:
+        app.logger.error(traceback.format_exc())
+        return jsonify({"code": 500, "error":
+                        "context content error: not a .yaml file!"})
+    except BaseException, e:
+        return returnServerError(e)
+
+    return jsonify({"code": 200, "result": "edit context success!"})
+###########################################################################
+
+
+def returnServerError(e, msg="Server Error"):
+    print e
+    app.logger.error(traceback.format_exc())
+    return jsonify({"code": 500, "error": msg})
+
+
+if __name__ == "__main__":
+    app.run(host='0.0.0.0', port=5310)