Ns descriptor related stuffs.
[vfc/nfvo/catalog.git] / catalog / packages / views / ns_descriptor_views.py
1 # Copyright 2018 ZTE Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import logging
16 import os
17 import traceback
18
19 from drf_yasg.utils import no_body, swagger_auto_schema
20 from rest_framework import status
21 from rest_framework.decorators import api_view
22 from rest_framework.response import Response
23 from django.http import FileResponse
24 from django.http import StreamingHttpResponse
25
26 from catalog.packages.biz.ns_descriptor import create, query_multiple, query_single, delete_single, upload, download
27 from catalog.packages.serializers.create_nsd_info_request import \
28     CreateNsdInfoRequestSerializer
29 from catalog.packages.serializers.nsd_info import NsdInfoSerializer
30 from catalog.packages.serializers.nsd_infos import NsdInfosSerializer
31 from catalog.pub.exceptions import CatalogException
32
33 logger = logging.getLogger(__name__)
34
35
36 @swagger_auto_schema(
37     method='GET',
38     operation_description="Query an individual NS descriptor resource",
39     request_body=no_body,
40     responses={
41         status.HTTP_200_OK: NsdInfoSerializer(),
42         status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
43     }
44 )
45 @swagger_auto_schema(
46     method='DELETE',
47     operation_description="Delete an individual NS descriptor resource",
48     request_body=no_body,
49     responses={
50         status.HTTP_204_NO_CONTENT: {},
51         status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
52     }
53 )
54 @api_view(http_method_names=['GET', 'DELETE'])
55 def ns_info_rd(request, nsdInfoId):
56     if request.method == 'GET':
57         try:
58             data = query_single(nsdInfoId)
59             nsd_info = NsdInfoSerializer(data=data)
60             if not nsd_info.is_valid():
61                 raise CatalogException
62             return Response(data=nsd_info.data, status=status.HTTP_200_OK)
63         except CatalogException:
64             logger.error(traceback.format_exc())
65             return Response(
66                 data={'error': 'Query of an individual NS descriptor resource failed.'},
67                 status=status.HTTP_500_INTERNAL_SERVER_ERROR
68             )
69
70     if request.method == 'DELETE':
71         try:
72             data = delete_single(nsdInfoId)
73             return Response(data={}, status=status.HTTP_204_NO_CONTENT)
74         except CatalogException:
75             logger.error(traceback.format_exc())
76             return Response(
77                 data={'error': 'Deletion of an individual NS descriptor resource failed.'},
78                 status=status.HTTP_500_INTERNAL_SERVER_ERROR
79             )
80
81
82 @swagger_auto_schema(
83     method='POST',
84     operation_description="Create an individual NS descriptor resource",
85     request_body=CreateNsdInfoRequestSerializer(),
86     responses={
87         status.HTTP_201_CREATED: NsdInfoSerializer(),
88         status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
89     }
90 )
91 @swagger_auto_schema(
92     method='GET',
93     operation_description="Query multiple NS descriptor resources",
94     request_body=no_body,
95     responses={
96         status.HTTP_200_OK: NsdInfosSerializer(),
97         status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
98     }
99 )
100 @api_view(http_method_names=['POST', 'GET'])
101 def ns_descriptors_rc(request, *args, **kwargs):
102     if request.method == 'POST':
103         try:
104             create_nsd_info_requst = CreateNsdInfoRequestSerializer(data=request.data)
105             if not create_nsd_info_requst.is_valid():
106                 raise CatalogException
107             data = create(create_nsd_info_requst.data)
108             nsd_info = NsdInfoSerializer(data=data)
109             if not nsd_info.is_valid():
110                 raise CatalogException
111             return Response(data=nsd_info.data, status=status.HTTP_201_CREATED)
112         except CatalogException:
113             logger.error(traceback.format_exc())
114             return Response(data={'error': 'Creating nsd info failed.'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
115
116     if request.method == 'GET':
117         try:
118             data = query_multiple()
119             nsd_infos = NsdInfosSerializer(data=data)
120             if not nsd_infos.is_valid():
121                 raise CatalogException
122             return Response(data=nsd_infos.data, status=status.HTTP_200_OK)
123         except CatalogException:
124             logger.error(traceback.format_exc())
125             return Response(
126                 data={'error': 'Query of multiple NS descriptor resources failed.'},
127                 status=status.HTTP_500_INTERNAL_SERVER_ERROR
128             )
129
130
131 @swagger_auto_schema(
132     method='PUT',
133     operation_description="Upload NSD content",
134     request_body=no_body,
135     responses={
136         status.HTTP_204_NO_CONTENT: {},
137         status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
138     }
139 )
140 @swagger_auto_schema(
141     method='GET',
142     operation_description="Fetch NSD content",
143     request_body=no_body,
144     responses={
145         status.HTTP_204_NO_CONTENT: {},
146         status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal error"
147     }
148 )
149 @api_view(http_method_names=['PUT', 'GET'])
150 def nsd_content_ru(request, *args, **kwargs):
151     nsd_info_id = kwargs.get("nsdInfoId")
152     if request.method == 'PUT':
153         files = request.FILES.getlist('file')
154         try:
155             upload(files[0], nsd_info_id)
156             return Response(data={}, status=status.HTTP_204_NO_CONTENT)
157         except IOError:
158             logger.error(traceback.format_exc())
159             raise CatalogException
160             return Response(data={'error': 'Uploading nsd content failed.'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
161
162     if request.method == 'GET':
163         try:
164             file_path = download(nsd_info_id)
165             file_name = file_path.split('/')[-1]
166             file_name = file_name.split('\\')[-1]
167
168             file_range = request.META.get('RANGE')
169             if file_range:
170                 [start, end] = file_range.split('-')
171                 start, end = start.strip(), end.strip()
172                 start, end = int(start), int(end)
173                 response = StreamingHttpResponse(
174                     read_partial_file(file_path, start, end),
175                     status=status.HTTP_200_OK
176                 )
177                 response['Content-Range'] = file_range
178             else:
179                 response = FileResponse(open(file_path, 'rb'), status=status.HTTP_200_OK)
180             response['Content-Disposition'] = 'attachment; filename=%s' % file_name.encode('utf-8')
181             response['Content-Length'] = os.path.getsize(file_path)
182             return response
183         except IOError:
184             logger.error(traceback.format_exc())
185             raise CatalogException
186             return Response(data={'error': 'Downloading nsd content failed.'},
187                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
188
189
190 def read_partial_file(file_path, start, end):
191     fp = open(file_path, 'rb')
192     fp.seek(start)
193     pos = start
194     CHUNK_SIZE = 1024 * 8
195     while pos + CHUNK_SIZE < end:
196         yield fp.read(CHUNK_SIZE)
197         pos = fp.tell()
198     yield fp.read(end - pos)