From 63bf19e9be7fe29fc691bef4088ec544444a4a19 Mon Sep 17 00:00:00 2001 From: SudhakarReddy Date: Tue, 27 Mar 2018 21:12:49 +0530 Subject: Multpart support:New API added Change-Id: I927be246ad422e276fda5d3913e3a0537072279e Issue-ID: MULTICLOUD-180 Signed-off-by: SudhakarReddy --- multivimbroker/multivimbroker/forwarder/base.py | 24 +++++++++++++++ multivimbroker/multivimbroker/forwarder/urls.py | 3 ++ multivimbroker/multivimbroker/forwarder/views.py | 36 ++++++++++++++++++++++ .../multivimbroker/pub/utils/restcall.py | 35 +++++++++++++++++++++ multivimbroker/requirements.txt | 3 ++ 5 files changed, 101 insertions(+) (limited to 'multivimbroker') diff --git a/multivimbroker/multivimbroker/forwarder/base.py b/multivimbroker/multivimbroker/forwarder/base.py index 534ac7a..512bb6a 100644 --- a/multivimbroker/multivimbroker/forwarder/base.py +++ b/multivimbroker/multivimbroker/forwarder/base.py @@ -19,6 +19,7 @@ import multivimbroker.pub.exceptions as exceptions from multivimbroker.pub.utils.syscomm import getHeadersKeys from multivimbroker.pub.utils.syscomm import getMultivimDriver from multivimbroker.pub.utils.restcall import req_by_msb +from multivimbroker.pub.utils.restcall import req_by_msb_multipart logger = logging.getLogger(__name__) @@ -29,6 +30,8 @@ class BaseHandler(object): def _request(self, route_uri, method, body="", headers=None): try: + if "multipart" in route_uri: + return self._multipart_req(route_uri, method, body, headers) retcode, content, status_code, resp = \ req_by_msb(route_uri, method, body, headers) if retcode != 0: @@ -49,6 +52,27 @@ class BaseHandler(object): response[k] = resp[k] return response + def _multipart_req(self, route_uri, method, body, headers=None): + + try: + retcode, content, status_code, resp = \ + req_by_msb_multipart(route_uri, method, body, headers) + if retcode != 0: + # Execptions are handled within req_by_msb + logger.error("Status code is %s, detail is %s.", + status_code, content) + + except exceptions.NotFound as e: + return HttpResponse(str(e), status=status.HTTP_404_NOT_FOUND) + + except Exception as e: + content = e + status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + logger.exception("exception: %s" % e) + + response = HttpResponse(content, status=status_code) + return response + def send(self, vimid, full_path, body, method, headers=None): try: diff --git a/multivimbroker/multivimbroker/forwarder/urls.py b/multivimbroker/multivimbroker/forwarder/urls.py index 771f052..3f11588 100644 --- a/multivimbroker/multivimbroker/forwarder/urls.py +++ b/multivimbroker/multivimbroker/forwarder/urls.py @@ -23,6 +23,7 @@ from multivimbroker.forwarder.views import Identity from multivimbroker.forwarder.views import Registry from multivimbroker.forwarder.views import UnRegistry from multivimbroker.forwarder.views import VIMTypes +from multivimbroker.forwarder.views import MultiPartView urlpatterns = [ @@ -40,6 +41,8 @@ urlpatterns = [ UnRegistry.as_view()), url(r'^api/multicloud/v0/(?P[0-9a-zA-Z_-]+)/extensions$', Extension.as_view()), + url(r'^api/multicloud/v0/(?P[0-9a-zA-Z_-]+)/multipart', + MultiPartView.as_view()), url(r'^api/multicloud/v0/(?P[0-9a-zA-Z_-]+)', Forward.as_view()), ] diff --git a/multivimbroker/multivimbroker/forwarder/views.py b/multivimbroker/multivimbroker/forwarder/views.py index d1763c2..a5dd22c 100644 --- a/multivimbroker/multivimbroker/forwarder/views.py +++ b/multivimbroker/multivimbroker/forwarder/views.py @@ -13,7 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import json +import tempfile +from poster.encode import multipart_encode +from poster.streaminghttp import register_openers from rest_framework.views import APIView from rest_framework.views import Response @@ -21,6 +25,7 @@ from rest_framework.views import status from multivimbroker.forwarder.base import BaseHandler from multivimbroker.pub.utils.syscomm import originHeaders from multivimbroker.pub.utils import syscomm +from rest_framework.parsers import MultiPartParser class BaseServer(BaseHandler, APIView): @@ -150,3 +155,34 @@ class Forward(BaseServer): return self.send(vimid, request.get_full_path(), request.body, "PUT", headers=None) + + +# Multipart view +class MultiPartView(BaseServer): + + parser_classes = (MultiPartParser, ) + + def post(self, request, vimid): + try: + register_openers() + fileDict = dict(request.FILES.iterlists()) + params = {} + for key in fileDict.keys(): + fileObj = fileDict[key][0] + f = tempfile.NamedTemporaryFile(prefix="django_", + suffix=fileObj._name, + delete=False) + f.write(fileObj.file.read()) + f.seek(fileObj.file.tell(), 0) + fileObj.file.close() + params[key] = open(f.name, 'rb') + datagen, headers = multipart_encode(params) + resp = self.send(vimid, request.path, datagen, "POST", + headers=originHeaders(request)) + finally: + for key in params: + fileRef = params[key] + if fileRef.closed is False: + fileRef.close() + os.remove(fileRef.name) + return resp diff --git a/multivimbroker/multivimbroker/pub/utils/restcall.py b/multivimbroker/multivimbroker/pub/utils/restcall.py index 23cb963..c839f61 100644 --- a/multivimbroker/multivimbroker/pub/utils/restcall.py +++ b/multivimbroker/multivimbroker/pub/utils/restcall.py @@ -34,6 +34,35 @@ HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '401', '400' logger = logging.getLogger(__name__) +def call_multipart_req(base_url, user, passwd, auth_type, resource, method, + content, headers=None): + callid = str(uuid.uuid1()) +# logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % ( +# callid, base_url, user, passwd, auth_type, resource, method, content)) + ret = None + resp = "" + full_url = "" + + try: + full_url = combine_url(base_url, resource) + logger.debug("request=%s)" % full_url) + requestObj = urllib2.Request(full_url, content, + headers) + resp = urllib2.urlopen(requestObj) + if resp.code in status_ok_list: + ret = [0, resp.read(), resp.code, resp] + else: + ret = [1, resp.read(), resp.code, resp] + except urllib2.URLError as err: + ret = [2, str(err), resp.code, resp] + except Exception: + logger.error(traceback.format_exc()) + logger.error("[%s]ret=%s" % (callid, str(sys.exc_info()))) + res_info = str(sys.exc_info()) + ret = [3, res_info, 500, resp] + return ret + + def call_req(base_url, user, passwd, auth_type, resource, method, content='', headers=None): callid = str(uuid.uuid1()) @@ -101,6 +130,12 @@ def req_by_msb(resource, method, content='', headers=None): rest_no_auth, resource, method, content, headers) +def req_by_msb_multipart(resource, method, content, headers=None): + base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT) + return call_multipart_req(base_url, "", "", + rest_no_auth, resource, method, content, headers) + + def get_res_from_aai(resource, content=''): headers = { 'X-FromAppId': 'MultiCloud', diff --git a/multivimbroker/requirements.txt b/multivimbroker/requirements.txt index 5aadc57..b7cdb47 100644 --- a/multivimbroker/requirements.txt +++ b/multivimbroker/requirements.txt @@ -2,6 +2,9 @@ Django==1.9.6 djangorestframework==3.3.3 +#multipart support +poster==0.8.1 + # redis cache redis==2.10.5 -- cgit 1.2.3-korg