Index: /branches/amp_3_7/extensions/monitoring/webui/monitoring.service.js
===================================================================
--- /branches/amp_3_7/extensions/monitoring/webui/monitoring.service.js	(revision 2490)
+++ /branches/amp_3_7/extensions/monitoring/webui/monitoring.service.js	(working copy)
@@ -15,6 +15,7 @@
                 getVirtualService: getVirtualService,
                 getRealService: getRealService,
                 getVirtualSite: getVirtualSite,
+                getLLBLinks: getLLBLinks,
             };
 
             function getDeviceList() {
@@ -123,6 +124,31 @@
                 });
                 return deferred.promise;
             }
+            function getLLBLinks(device_ip) {
+                let deferred = $q.defer();
+                let payload = {
+                    "action": "get_threshold_stats",
+                    "query": {
+                        "serviceType": "LLB",
+                        "device_ip": device_ip
+                    }
+                }
+                dashboardService.composer_query(payload).then(function (res) {
+                    var serverList = []
+                    if (res && res.status === 200) {
+                        _.each(res.data.results[0].series, function (series) {
+                            serverList.push({
+                                "name": series.tags.linkName,
+                                "origin_type": "LLB",
+                                "device_ip": device_ip
+                            })
+                        })
+                    }
+                    deferred.resolve(serverList);
+                });
+                return deferred.promise;
+            }
         }
     ]);
 
+
Index: /branches/amp_3_7/extensions/monitoring/webui/reporting/tabs/cron_reportings/cron_reportings.controller.js
===================================================================
--- /branches/amp_3_7/extensions/monitoring/webui/reporting/tabs/cron_reportings/cron_reportings.controller.js	(revision 2490)
+++ /branches/amp_3_7/extensions/monitoring/webui/reporting/tabs/cron_reportings/cron_reportings.controller.js	(working copy)
@@ -381,13 +381,16 @@
                                             serviceList.push(...resp)
                                             monitoringService.getRealService(host.ip).then(function (resp) {
                                                 serviceList.push(...resp)
-                                                _.each(serviceList, function (data) {
-                                                    if (data.name == service_name) {
-                                                        modalViewModel.subject = JSON.stringify(data);
-                                                    }
-                                                });
-                                                modalViewModel.subjectList = serviceList;
-                                                modalViewModel.loadingSubject = false;
+                                                monitoringService.getLLBLinks(host.ip).then(function (llbLinks) {
+                                                    serviceList.push(...llbLinks)
+                                                    _.each(serviceList, function (data) {
+                                                        if (data.name == service_name) {
+                                                            modalViewModel.subject = JSON.stringify(data);
+                                                        }
+                                                    });
+                                                    modalViewModel.subjectList = serviceList;
+                                                    modalViewModel.loadingSubject = false;
+                                                })
                                             })
                                         });
                                     } else if (host.general_type == 'vpn') {
@@ -414,7 +417,8 @@
             } else if (modalViewModel.subject_type == "device_patrol") {
                 modalViewModel.subjectList = [
                     { "name": (CMSettings.app == "AMP") ? "Server Load Balance" : "SSL Security Gateway", "verbose_name": (CMSettings.app == "AMP") ? "Server Load Balance" : "SSL Security Gateway" },
-                    { "name": "SSLVPN", "verbose_name": "SSLVPN" }
+                    { "name": "SSLVPN", "verbose_name": "SSLVPN" },
+                    { "name": "LLB", "verbose_name": "Link Load Balancers" },
                 ];
                 if (modalData.args.subject) {
                     modalViewModel.subject = JSON.stringify(modalData.args.subject);
@@ -478,7 +482,8 @@
                 } else if (modalViewModel.subject_type == "device_patrol") {
                     modalViewModel.subjectList = [
                         { "name": (CMSettings.app == "AMP") ? "Server Load Balance" : "SSL Security Gateway", "verbose_name": (CMSettings.app == "AMP") ? "Server Load Balance" : "SSL Security Gateway" },
-                        { "name": "SSLVPN", "verbose_name": "SSLVPN" }
+                        { "name": "SSLVPN", "verbose_name": "SSLVPN" },
+                        { "name": "LLB", "verbose_name": "Link Load Balancers" },
                     ];
                     modalViewModel.subject = JSON.stringify({ "name": (CMSettings.app == "AMP") ? "Server Load Balance" : "SSL Security Gateway", "verbose_name": (CMSettings.app == "AMP") ? "Server Load Balance" : "SSL Security Gateway" });
                 } else if (modalViewModel.subject_type == "automatic_diagnose") {
@@ -502,8 +507,11 @@
                             serviceList.push(...res)
                             monitoringService.getRealService(host.ip).then(function (res) {
                                 serviceList.push(...res)
-                                modalViewModel.subjectList = serviceList;
-                                modalViewModel.loadingSubject = false;
+                                monitoringService.getLLBLinks(host.ip).then(function (llbLinks) {
+                                    serviceList.push(...llbLinks)
+                                    modalViewModel.subjectList = serviceList;
+                                    modalViewModel.loadingSubject = false;
+                                })
                             })
                         });
                     } else if (device_type_info.VPN_TYPE_LIST.indexOf(host.type.toLowerCase()) != -1) {
@@ -549,7 +557,6 @@
                         to_str = "now";
                     }
                 } else {
-                    //构建时间条件
                     var from = new Date();
                     var to = new Date();
 
@@ -688,3 +695,4 @@
             }
         }
     ]);
+
Index: /branches/amp_3_7/extensions/monitoring/webui/reporting/tabs/gen_reportings/gen_reportings.html
===================================================================
--- /branches/amp_3_7/extensions/monitoring/webui/reporting/tabs/gen_reportings/gen_reportings.html	(revision 2490)
+++ /branches/amp_3_7/extensions/monitoring/webui/reporting/tabs/gen_reportings/gen_reportings.html	(working copy)
@@ -25,7 +25,7 @@
                                 <th st-sort="name">{{ 'Task Name' | T }}</th>
                                 <th st-sort="subject_name">{{ 'Subject Name' | T }}</th>
                                 <th>{{ 'Status' | T }}</th>
-                                <th>{{ 'Time Cost' | T }}</th>
+<!--                                <th>{{ 'Time Cost' | T }}</th>-->
                                 <th>{{ 'Action' | T }}</th>
                             </tr>
                             <tr>
@@ -64,7 +64,7 @@
                                     <span title="{{'Finished'|T}}" ng-if="item.status == 2"><i class="fa fa-check-square" style="color: green;"></i></span>
                                     <span title="{{'Cancel'|T}}" ng-if="item.status == 3"><i class="fa fa-minus-square" style="color: grey;"></i></span>
                                 </td>
-                                <td>{{ item.total_time}}</td>
+<!--                                <td>{{ item.total_time}}</td>-->
                                 <td>
                                     <a title="{{'Delete'|T}}" ng-if="item.status != 1" ng-click="reporting.delete(item)" class="text-explode"><i class="fa fa-times-circle"></i></a>
                                     <a title="{{'Download'|T}}" ng-if="item.status == 2" ng-click="reporting.download(item)" class="text-explode"><i class="fa fa-download"></i></a>
@@ -93,6 +93,6 @@
 
 <style>
     .text-explode {
-        margin: 0px 3px !important;
+        margin: 0 3px !important;
     }
-</style>
\ No newline at end of file
+</style>
Index: /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/composer.py
===================================================================
--- /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/composer.py	(revision 2490)
+++ /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/composer.py	(working copy)
@@ -20,6 +20,7 @@
 from lib.response import FileResponse
 from hive.services import composer_query_service
 from revproxy.views import ProxyView
+from hive.report.generate_report import handle_report_generation, is_llb_report
 
 ELASTIC_SEARCH_CONFIG_FILE = '/etc/elasticsearch/elasticsearch.yml'
 
@@ -153,9 +154,6 @@
     else:
         query_string += "&time=" + timestamp + "&sign=" + m.hexdigest()
 
-    # for k, v in request.environ.items():
-    #     print(k, v)
-
     httpClient = None
 
     if 'CONTENT_TYPE' in request.environ:
@@ -163,6 +161,13 @@
     else:
         config = {}
     try:
+        # Override existing functionality of task execution for LLB Reports. - update to better approach when we have composer replacement.
+        if "report/run/" in path:
+            report_id = int(path.split("/")[2])
+            is_llb, payload = is_llb_report(report_id)
+            if is_llb:
+                query_output = handle_report_generation(payload)
+                return HttpResponse(json.dumps(query_output), content_type='application/json')
         httpClient = httplib.HTTPConnection(CMDATA['COMPOSER_IP'], str(CMDATA['COMPOSER_PORT']), True, timeout=300)
         httpClient.request(request.method, url + "?" + query_string, request.body, config)
         response = httpClient.getresponse()
@@ -614,3 +619,4 @@
         return elastic_status(request)
     elif app == 'kibana':
         return kibana_status(request)
+
Index: /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/db/llb_stats_queries.py
===================================================================
--- /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/db/llb_stats_queries.py	(revision 2490)
+++ /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/db/llb_stats_queries.py	(working copy)
@@ -288,6 +288,7 @@
             "now-24h": 86400000,  # 24 hours in ms
             "now-2d": 172800000,  # 2 days in ms
             "now-7d": 604800000,  # 7 days in ms
+            "now-1w": 604800000,  # 7 days in ms
             "now-30d": 2592000000,  # 30 days in ms
             "now-60d": 5184000000,  # 60 days in ms
             "now-90d": 7776000000,  # 90 days in ms
@@ -317,6 +318,7 @@
             "now-24h": "now()-24h",  # 24 hours in ms
             "now-2d": "now()-2d",  # 2 days in ms
             "now-7d": "now()-7d",  # 7 days in ms
+            "now-1w": "now()-1w",  # 7 days in ms
             "now-30d": "now()-30d",  # 30 days in ms
             "now-60d": "now()-60d",  # 60 days in ms
             "now-90d": "now()-90d",  # 90 days in ms
@@ -358,4 +360,4 @@
     def format_query_string(query):
         """Formats query string to ensure proper URL encoding"""
         return query.strip().replace(' ', "%20").replace('<', "%3C").replace('>', "%3E").replace(',', "%2C") \
-            .replace(';', "%3B").replace('+', "%2B").replace('/', "%2F").replace('|', "%7C").replace('=', "%3D")
\ No newline at end of file
+            .replace(';', "%3B").replace('+', "%2B").replace('/', "%2F").replace('|', "%7C").replace('=', "%3D")
Index: /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/report/generate_pdf_report.py
===================================================================
--- /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/report/generate_pdf_report.py	(revision 2490)
+++ /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/report/generate_pdf_report.py	(working copy)
@@ -9,7 +9,6 @@
 from hive.utils import andebug
 from cm.lib.libbasic_operation import oper_log
 
-report_file_path = "/ca/webui/htdocs/new/src/hive/media/docs/"
 logo_path = "/ca/webui/htdocs/new/src/hive/media/static/Array-Logo-en-2024.jpg"
 
 
@@ -34,12 +33,12 @@
                                        ('FONT', (0, 0), (-1, -1), 'Helvetica'), ]))
         return table
 
-    def generate_pdf_report(self, filename, category, llb_data_dict, link_data_summary_dict, start_time, end_time):
+    def generate_pdf_report(self, filename, report_directory_path, category, llb_data_dict, link_data_summary_dict, start_time, end_time):
         try:
             """
                 Generate a PDF report with a table and an optional chart.
             """
-            pdf = SimpleDocTemplate(report_file_path + filename, pagesize=letter)
+            pdf = SimpleDocTemplate(report_directory_path + filename, pagesize=letter)
             elements = []
             styles = getSampleStyleSheet()
             styles.add(ParagraphStyle(
@@ -124,4 +123,5 @@
             pdf.build(elements)
         except Exception as e:
             oper_log('error', 'system', e.message)
-            raise e  # Raise to crash and see error
\ No newline at end of file
+            raise e  # Raise to crash and see error
+
Index: /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/report/generate_report.py
===================================================================
--- /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/report/generate_report.py	(revision 2490)
+++ /branches/amp_3_7/src/webui/webui/htdocs/new/src/hive/report/generate_report.py	(working copy)
@@ -1,5 +1,6 @@
 import os
-
+import shutil
+import sqlite3
 from django.http import HttpResponse
 import json
 import time
@@ -10,19 +11,44 @@
 from hive.llb_stats import reformat_data_from_db
 from hive.utils import andebug
 
-report_file_path = "/ca/webui/htdocs/new/src/hive/media/docs/"
+COMPOSER_DATA_PATH = "/var/opt/composer/reporting/data/"
+COMPOSER_DB = "/var/opt/composer/ui/conf/composer.db"
 
 
-def handle_report_generation(request, path=None):
+def is_llb_report(report_id):
     try:
-        if path == 'pdf' and request.method == 'POST':
-            return generate_pdf_report(request)
-        else:
-            return HttpResponse(json.dumps({
-                'error': 405,
-                'message': "Invalid HTTP method"
-            }), content_type='application/json')
-
+        connection_obj = sqlite3.connect(COMPOSER_DB)
+        cursor_obj = connection_obj.cursor()
+        statement = "select name, args, tags, notify_status, notifications from report where id = %d;" % report_id
+        cursor_obj.execute(statement)
+        query_output = cursor_obj.fetchone()
+        task_name = query_output[0]
+        args = json.loads(query_output[1])
+        tags = json.loads(query_output[2])
+        notify_status = query_output[3]
+        notifications = query_output[4]
+        connection_obj.close()
+        payload = {
+            "report_id": report_id,
+            "task_name": task_name,
+            "tags": tags,
+            "from_time": args.get('from'),
+            "to_time": args.get('to')
+        }
+        device_category = None
+        link_name = None
+        if "name" in args["subject"] and args["subject"]["name"] == "LLB" and "device_patrol" in tags:
+            device_category = args["subject"]["name"]
+        elif "origin_type" in args["subject"] and args["subject"]["origin_type"] == "LLB" and "service_status" in tags:
+            link_name = args["subject"]["name"]
+            device_category = "LLB"
+        if device_category is not None:
+            payload["category"] = device_category
+        if link_name is not None:
+            payload["link_name"] = link_name
+        if link_name is None and device_category is None:
+            return False, payload
+        return True, payload
     except ge.GenericError as e:
         oper_log('error', 'system', e.message)
         return ge.handle_exception(e)
@@ -32,50 +58,86 @@
         return ge.handle_exception(e)
 
 
-def generate_pdf_report(request):
+def handle_report_generation(payload):
     try:
-        req = json.loads(request.body)
+        return generate_pdf_report(payload)
+    except ge.GenericError as e:
+        oper_log('error', 'system', e.message)
+        return ge.handle_exception(e)
+    except Exception as e:
+        oper_log('error', 'system', 'An Unexpected error occurred,  details: {}'.format(e))
+        e.message = 'An Unexpected error occurred,  details: {}'.format(e)
+        return ge.handle_exception(e)
 
-        if 'query' in req and 'from_time' in req['query'] and 'to_time' in req['query']:
-            from_time = req['query'].get('from_time', '')
-            to_time = req['query'].get('to_time', '')
-            category = req['query'].get('category')
-            link_name = req['query'].get('link_name', '')
-        else:
-            oper_log('error', 'system',
-                     "Query cannot be empty. Please specify from_time and to_time and link_name in the query.")
-            raise ge.GenericError(400, "Query cannot be empty. Please specify from_time and to_time and link_name in "
-                                       "the query.")
 
+def generate_pdf_report(payload):
+    try:
+        report_id = payload.get("report_id")
+        task_name = payload.get("task_name")
+        from_time = payload.get("from_time", "")
+        to_time = payload.get("to_time", "")
+        category = payload.get("category", "")
+        link_name = payload.get("link_name", "")
+        tags = json.dumps(payload.get("tags", ""))
         if category and str(category).upper() == 'LLB':
             data_dict = get_llb_detailed_data_for_report(from_time, to_time, link_name)
             data_summary_dict = get_link_summary_data_for_report(from_time, to_time)
         else:
-            oper_log('error', 'system',
-                     "category cannot be empty. Please specify category in the query.")
-            raise ge.GenericError(400, "category cannot be empty. Please specify category in the query.")
+            oper_log('error', 'system', "category cannot be empty. Please specify category in the query.")
+            raise Exception("Error while generating PDF")
 
         report_generator = Report()
+        report_directory_path = COMPOSER_DATA_PATH + "%d/" % report_id
+        if not os.path.exists(report_directory_path):
+            os.makedirs(report_directory_path)
         intervalStart, intervalEnd = LLBStatsDB.get_time_range(from_time, to_time)
-        start_time = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime(intervalEnd / 1000))
-        end_time = time.strftime("%Y_%m_%d_%H_%M_%S",
-                      time.localtime(intervalStart / 1000))
-        report_name = str(category).upper() + "_" + "Statistics_Report_from_%s_to_%s.pdf" % (
-        start_time, end_time)
-
-        report_generator.generate_pdf_report(report_name, category, data_dict, data_summary_dict, intervalStart, intervalEnd)
-        if os.path.exists(report_file_path + report_name):
-            return HttpResponse(json.dumps({"result": True, "filename": report_name}), content_type='application/json')
-        else:
-            return HttpResponse(json.dumps({"result": False}), content_type='application/json')
 
-    except ge.GenericError as e:
-        oper_log('error', 'system', e.message)
-        return ge.handle_exception(e)
-    except Exception as e:
-        oper_log('error', 'system', e.message)
-        return HttpResponse(json.dumps({"error": "Error while generating PDF",
-                                        }), content_type='application/json')
+        report_name = str(task_name).upper() + "_" + "%s_%s.pdf" % (intervalStart, intervalEnd)
+
+        report_generator.generate_pdf_report(report_name, report_directory_path, category, data_dict, data_summary_dict,
+                                             intervalStart, intervalEnd)
+
+        # Update the entry in DB
+        connection_obj = sqlite3.connect(COMPOSER_DB)
+        cursor_obj = connection_obj.cursor()
+        report_status = 2
+        file_size_bytes = os.path.getsize(report_directory_path + report_name)
+        file_size_kb = file_size_bytes / 1024.0
+        result = json.dumps({"file_name": report_name, "format": "pdf", "language": "en", "message": "success",
+                             "size": '%.2f K' % file_size_kb})
+        statement = "insert into report_log (report_id, name, tags, start_time, end_time, status, result) values (%d, '%s', '%s', '%s', '%s', '%s', '%s');" % (
+            report_id, task_name, tags, intervalStart, intervalEnd, report_status, result)
+        cursor_obj.execute(statement)
+        connection_obj.commit()
+        connection_obj.close()
+
+        if os.path.exists(report_directory_path + report_name):
+            connection_obj = sqlite3.connect(COMPOSER_DB)
+            cursor_obj = connection_obj.cursor()
+            statement = "select id from report_log where report_id = %d order by id desc;" % report_id
+            cursor_obj.execute(statement)
+            query_output = cursor_obj.fetchone()
+            report_log_id = query_output[0]
+            task_report_path = COMPOSER_DATA_PATH + "%d/" % report_log_id
+            if not os.path.exists(task_report_path):
+                os.makedirs(task_report_path)
+            shutil.move(report_directory_path + report_name, task_report_path)
+
+            if os.path.exists(task_report_path + report_name):
+                return {
+                    'code': 0,
+                    'data': None,
+                    'message': "The report is being generated. Check report_log."
+                }
+        return {
+            'code': -1,
+            'data': None,
+            'message': "Report generation failed. Please retry."
+        }
+
+    except Exception as exp:
+        oper_log('error', 'system', exp.message)
+        raise Exception("Error while generating PDF")
 
 
 def get_link_summary_data_for_report(from_time, to_time):
@@ -108,9 +170,7 @@
                     }
         else:
             if 'results' in response and all(len(res) == 1 and 'statement_id' in res for res in response['results']):
-                return HttpResponse(json.dumps({
-                    "error": "No valid data found"
-                }), content_type='application/json')
+                return []
             else:
                 return HttpResponse(json.dumps(response), content_type='application/json')
         return llb_dict
@@ -163,12 +223,11 @@
                     }
         else:
             if 'results' in response and all(len(res) == 1 and 'statement_id' in res for res in response['results']):
-                return HttpResponse(json.dumps({
-                    "error": "No valid data found"
-                }), content_type='application/json')
+                return []
             else:
                 return HttpResponse(json.dumps(response), content_type='application/json')
         return llb_dict
     except Exception as e:
         return HttpResponse(json.dumps({"error": "Error while fetching LLB data",
                                         }), content_type='application/json')
+
