Bladeren bron

优化查询消息列表V2获取OCI预认证URL改为授权前缀

zhangdongming 1 jaar geleden
bovenliggende
commit
7eff5ec10e
2 gewijzigde bestanden met toevoegingen van 73 en 60 verwijderingen
  1. 69 58
      Controller/DetectControllerV2.py
  2. 4 2
      Object/OCIObjectStorage.py

+ 69 - 58
Controller/DetectControllerV2.py

@@ -11,7 +11,7 @@ from django.views.generic.base import View
 
 from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN, \
     OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, LOGGER, ALGORITHM_COMBO_TYPES
-from Ansjer.config import PUSH_BUCKET, CONFIG_INFO, CONFIG_CN
+from Ansjer.config import PUSH_BUCKET, CONFIG_INFO, CONFIG_CN, CONFIG_EUR, CONFIG_US
 from Model.models import Device_Info, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel, \
     AiService, VodBucketModel
 from Object.ETkObject import ETkObject
@@ -334,8 +334,6 @@ class DetectControllerViewV2(View):
                 # 默认查询近七天内数据
                 end_time = int(time.time())
                 start_time = LocalDateTimeUtil.get_before_days_timestamp(end_time, 7)
-            # oci获取图片链接太慢了 app默认20条 暂时先减少分页条数
-            line = 10 if CONFIG_INFO != CONFIG_CN else line
             equipment_info_qs, count = EquipmentInfoService. \
                 union_equipment_info(userID, uid_list, event_type, start_time, end_time, page, line)
 
@@ -373,9 +371,9 @@ class DetectControllerViewV2(View):
                 region_name='cn-northwest-1'
             )
             # 国内生产环境默认不实例OCI对象
-            oci_eur = None if CONFIG_INFO == CONFIG_CN else OCIObjectStorage('eur')
-            oci_us = None if CONFIG_INFO == CONFIG_CN else OCIObjectStorage('us')
+            oci = self.get_oci_client()
             redis_obj = RedisObject(3)
+
             # ai消息标识所有组合标签
             ai_all_event_type = EquipmentInfoService.get_all_comb_event_type()
             for equipment_info in equipment_info_qs:
@@ -392,8 +390,10 @@ class DetectControllerViewV2(View):
                     if storage_location == 1:  # 阿里云oss
                         img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
                     elif storage_location in [3, 4]:
-                        oci = oci_eur if storage_location == 4 else oci_us
-                        img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
+                        prefix_name = f'{uid}/'
+                        img_url = DetectControllerViewV2.oci_object_url(oci, redis_obj, uid, prefix_name)
+                        if img_url:
+                            img_url = img_url + thumbspng
                     else:
                         params = {'Key': thumbspng}
                         if region == 1:  # AWS国外
@@ -446,33 +446,26 @@ class DetectControllerViewV2(View):
                     # 列表装载回放时间戳标记
                     equipment_info['img_list'] = []
 
-                    msg_key = f'{uid}:{channel}:{event_time}'
-                    # OCI三张图 获取缓存临时URL
-                    img_data = DetectControllerViewV2.get_msg_redis_url(redis_obj, msg_key,
-                                                                        equipment_info['is_st'], storage_location)
-                    if img_data:
-                        equipment_info['img_list'] = img_data
-                    else:
-                        for i in range(equipment_info['is_st']):
-                            thumbspng = '{}/{}/{}_{}.jpeg'.format(uid, channel, event_time, i)
-                            if storage_location == 1:  # 阿里云oss
-                                img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
-                            elif storage_location in [3, 4]:  # 国外OCI云
-                                oci = oci_eur if storage_location == 4 else oci_us
-                                img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
-                            else:
-                                params = {'Key': thumbspng}
-                                if region == 1:  # 国外AWS
-                                    params['Bucket'] = 'foreignpush'
-                                    img_url = aws_s3.generate_presigned_url(
-                                        'get_object', Params=params, ExpiresIn=300)
-                                else:  # 国内AWS
-                                    params['Bucket'] = 'push'
-                                    img_url = aws_s3_cn.generate_presigned_url(
-                                        'get_object', Params=params, ExpiresIn=300)
-                            equipment_info['img_list'].append(img_url)
-                        if not img_data and equipment_info['is_st'] == 3 and storage_location in [3, 4]:
-                            DetectControllerViewV2.set_msg_redis_url(redis_obj, msg_key, equipment_info['img_list'])
+                    for i in range(equipment_info['is_st']):
+                        thumbspng = '{}/{}/{}_{}.jpeg'.format(uid, channel, event_time, i)
+                        if storage_location == 1:  # 阿里云oss
+                            img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                        elif storage_location in [3, 4]:  # 国外OCI云
+                            prefix_name = f'{uid}/'
+                            img_url = DetectControllerViewV2.oci_object_url(oci, redis_obj, uid, prefix_name)
+                            if img_url:
+                                img_url = img_url + thumbspng
+                        else:
+                            params = {'Key': thumbspng}
+                            if region == 1:  # 国外AWS
+                                params['Bucket'] = 'foreignpush'
+                                img_url = aws_s3.generate_presigned_url(
+                                    'get_object', Params=params, ExpiresIn=300)
+                            else:  # 国内AWS
+                                params['Bucket'] = 'push'
+                                img_url = aws_s3_cn.generate_presigned_url(
+                                    'get_object', Params=params, ExpiresIn=300)
+                        equipment_info['img_list'].append(img_url)
 
                 if uid in uid_type_dict.keys():
                     equipment_info['uid_type'] = uid_type_dict[uid]['type']
@@ -494,30 +487,42 @@ class DetectControllerViewV2(View):
             return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     @staticmethod
-    def get_msg_redis_url(redis_client, msg_key, is_st, storage_location):
-        if is_st == 3 and storage_location in [3, 4]:
-            img_data = redis_client.get_data(msg_key)
-            if img_data:
-                return json.loads(img_data)
-        return None
-
-    @staticmethod
-    def set_msg_redis_url(redis_client, msg_key, img_list):
-        redis_client.set_data(msg_key, json.dumps(img_list), 580)
+    def get_oci_client():
+        """
+        获取所在区域客户端
+        @return:
+        """
+        if CONFIG_INFO == CONFIG_CN:
+            return None
+        oci = OCIObjectStorage(CONFIG_EUR) if CONFIG_INFO == CONFIG_EUR else OCIObjectStorage(CONFIG_US)
+        return oci
 
     @staticmethod
-    def oci_object_url(oci, obj_name):
+    def oci_object_url(oci, redis_obj, uid, obj_name):
         """
         获取OCI对象存储URL 有效期5分钟
-        @param oci:
-        @param obj_name: 对象名称
+        @param uid: 设备UID
+        @param redis_obj: 缓存客户端
+        @param oci: oci客户端
+        @param obj_name: 对象名称或前缀
         @return: url
         """
-        if not oci:
-            return ''
-        time_expires = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
-        result = oci.get_preauthenticated_request_url(PUSH_BUCKET, 'ociPush', obj_name, time_expires)
-        return result.full_path if result else ''
+        try:
+            if not oci:
+                return ''
+            uid_key = f'PUSH:MSG:OCI:URL:{uid}'
+            oci_url = redis_obj.get_data(uid_key)
+            if oci_url:
+                return oci_url
+            time_expires = datetime.datetime.utcnow() + datetime.timedelta(minutes=60)
+            result = oci.get_preauthenticated_request_url(PUSH_BUCKET, 'ociPush', obj_name, time_expires,
+                                                          'AnyObjectRead')  # 授权到指定uid文件夹
+            full_url = result.full_path if result else ''
+            redis_obj.set_data(uid_key, full_url, 3580)
+            return full_url
+        except Exception as e:
+            LOGGER.error('oci查询消息列表异常error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return
 
     def do_transfer(self, request_dict, response, userID):
         event_time = request_dict.get('eventTime', None)
@@ -560,8 +565,10 @@ class DetectControllerViewV2(View):
                 region_name='cn-northwest-1'
             )
 
-            oci_eur = OCIObjectStorage('eur')
-            oci_us = OCIObjectStorage('us')
+            # 国内生产环境默认不实例OCI对象
+            oci = self.get_oci_client()
+            redis_obj = RedisObject(3)
+
             # ai消息标识所有组合标签
             ai_all_event_type = EquipmentInfoService.get_all_comb_event_type()
             for equipment_info in equipment_info_qs:
@@ -578,8 +585,10 @@ class DetectControllerViewV2(View):
                     if storage_location == 1:  # 阿里云oss
                         img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
                     elif storage_location in [3, 4]:
-                        oci = oci_eur if storage_location == 4 else oci_us
-                        img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
+                        prefix_name = f'{uid}/'
+                        img_url = DetectControllerViewV2.oci_object_url(oci, redis_obj, uid, prefix_name)
+                        if img_url:
+                            img_url = img_url + thumbspng
                     else:
                         params = {'Key': thumbspng}
                         if region == 1:  # AWS国外
@@ -636,8 +645,10 @@ class DetectControllerViewV2(View):
                         if storage_location == 1:  # 阿里云oss
                             img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
                         elif storage_location in [3, 4]:
-                            oci = oci_eur if storage_location == 4 else oci_us
-                            img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
+                            prefix_name = f'{uid}/'
+                            img_url = DetectControllerViewV2.oci_object_url(oci, redis_obj, uid, prefix_name)
+                            if img_url:
+                                img_url = img_url + thumbspng
                         else:
                             params = {'Key': thumbspng}
                             if region == 1:  # 国外AWS

+ 4 - 2
Object/OCIObjectStorage.py

@@ -55,13 +55,15 @@ class OCIObjectStorage:
             print(repr(e))
             return None
 
-    def get_preauthenticated_request_url(self, bucket_name, name, object_name, time_expires):
+    def get_preauthenticated_request_url(self, bucket_name, name, object_name, time_expires, access_type='ObjectRead'):
         """
         获取指定对象预认证请求URL。
         @param bucket_name: 存储桶名称
         @param name: 请求名称 是创建的预授权链接的名称,是方便管理用的,不会影响功能。比如对每个桶分别创建链接,如果要删除或者查看,可以根据name看出来是对哪个桶的链接。
         @param object_name: 对象名
         @param time_expires: 失效时间 需要datetime类型格式 例如:datetime.utcnow() + timedelta(minutes=30)
+        @param access_type: 授权类型(https://docs.oracle.com/en-us/iaas/tools/python/2.127.0/api/object_storage/models/oci.
+        object_storage.models.CreatePreauthenticatedRequestDetails.html#oci.object_storage.models.CreatePreauthenticatedRequestDetails.access_type)
         @return: 预认证请求URL
         """
         try:
@@ -73,7 +75,7 @@ class OCIObjectStorage:
                 create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
                     name=name,
                     object_name=object_name,
-                    access_type="ObjectRead",
+                    access_type=access_type,
                     time_expires=time_expires
                 )
             )