Adapting GUI for error report managing 59/89759/9
authorBartosz Gardziejewski <bartosz.gardziejewski@nokia.com>
Wed, 12 Jun 2019 13:55:45 +0000 (15:55 +0200)
committerWojciech Sliwka <wojciech.sliwka@nokia.com>
Mon, 8 Jul 2019 07:01:14 +0000 (07:01 +0000)
Change-Id: Idb3f5750596334990b030bfdf2f6551ad4d1c8e3
Issue-ID: VID-488
Signed-off-by: Bartosz Gardziejewski <bartosz.gardziejewski@nokia.com>
27 files changed:
epsdk-app-onap/src/main/webapp/WEB-INF/jsp/serviceModels.jsp
vid-app-common/src/main/java/org/onap/vid/properties/Features.java
vid-app-common/src/main/webapp/WEB-INF/conf/dev.features.properties
vid-app-common/src/main/webapp/WEB-INF/conf/features.properties
vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js
vid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js
vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js
vid-app-common/src/main/webapp/app/vid/scripts/controller/creationDialogController.js
vid-app-common/src/main/webapp/app/vid/scripts/controller/msoCommitController.js
vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html
vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal-request.controller.js [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal-request.controller.test.js [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.controller.js [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.controller.test.js [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.css [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.html [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/services/reportService.js [new file with mode: 0644]
vid-app-common/src/main/webapp/app/vid/scripts/view-models/aaiGetSubs.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/aaiGetSubscriberList.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/aaiServiceTypes.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/aaiSubDetails.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/aaiSubViewEdit.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/createInstanceServiceModels.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/creationDialog.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/msoCommit.htm
vid-app-common/src/main/webapp/app/vid/scripts/view-models/serviceModels.htm

index 13d1d08..2410aa2 100755 (executable)
@@ -43,6 +43,8 @@
 <script src="app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.controller.js"></script>\r
 <script src="app/vid/scripts/modals/new-test-environment/new-test-environment.controller.js"></script>\r
 <script src="app/vid/scripts/modals/alert-modal/alert-modal.controller.js"></script>\r
+<script src="app/vid/scripts/modals/report-modal/report-modal.controller.js"></script>\r
+<script src="app/vid/scripts/modals/report-modal/report-modal-request.controller.js"></script>\r
 <script src="app/vid/scripts/controller/aaiSubscriberController.js"></script>\r
 <script src="app/vid/scripts/controller/creationDialogController.js"></script>\r
 <script src="app/vid/scripts/controller/iframeDialogController.js"></script>\r
@@ -87,6 +89,7 @@
 <script src="app/vid/scripts/services/vnfService.js"></script>\r
 <script src="app/vid/scripts/services/pnfService.js"></script>\r
 <script src="app/vid/scripts/services/crService.js"></script>\r
+<script src="app/vid/scripts/services/reportService.js"></script>\r
 <script src="app/vid/scripts/services/change-management.service.js"></script>\r
 <script src="app/vid/scripts/modals/cancel-pending-workflow/cancel-pending-workflow.controller.js"></script>\r
 <script src="app/vid/scripts/services/OwningEntityService.js"></script>\r
index 1c68e82..ea047d6 100644 (file)
@@ -62,7 +62,8 @@ public enum Features implements Feature {
     FLAG_1902_NEW_VIEW_EDIT,
     FLAG_EXP_USE_DEFAULT_HOST_NAME_VERIFIER,
     FLAG_1902_VNF_GROUPING,
-    FLAG_HANDLE_SO_WORKFLOWS
+    FLAG_HANDLE_SO_WORKFLOWS,
+    FLAG_CREATE_ERROR_REPORTS
     ;
 
     public boolean isActive() {
index 8ba1484..96903a4 100644 (file)
@@ -9,6 +9,7 @@ FLAG_NETWORK_TO_ASYNC_INSTANTIATION = false
 FLAG_SERVICE_MODEL_CACHE = true
 FLAG_SHOW_ASSIGNMENTS = true
 FLAG_HANDLE_SO_WORKFLOWS = true
+FLAG_CREATE_ERROR_REPORTS = true
 
 FLAG_SHOW_VERIFY_SERVICE = true
 FLAG_DUPLICATE_VNF = true
index 7bdc659..b7634aa 100644 (file)
@@ -26,6 +26,7 @@ FLAG_1810_CR_SOFT_DELETE_ALACARTE_VF_MODULE = true
 FLAG_1810_AAI_LOCAL_CACHE = true
 FLAG_EXP_USE_DEFAULT_HOST_NAME_VERIFIER = false
 FLAG_HANDLE_SO_WORKFLOWS = true
+FLAG_CREATE_ERROR_REPORTS = false
 
 # Modern UI (Drawing-Board; View/Edit)
 # - - - - - - - - - - - - - - - - - -
@@ -46,3 +47,4 @@ FLAG_EXP_ANY_ALACARTE_NEW_INSTANTIATION_UI = false
 FLAG_SUPPLEMENTARY_FILE = false
 FLAG_1902_NEW_VIEW_EDIT=false
 FLAG_1902_VNF_GROUPING = false
+
index fc3d8f7..5c58018 100755 (executable)
@@ -258,7 +258,8 @@ appDS2
       FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST: "FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST",
       FLAG_1810_CR_LET_SELECTING_COLLECTOR_TYPE_UNCONDITIONALLY: "FLAG_1810_CR_LET_SELECTING_COLLECTOR_TYPE_UNCONDITIONALLY",
       FLAG_1810_CR_SOFT_DELETE_ALACARTE_VF_MODULE: "FLAG_1810_CR_SOFT_DELETE_ALACARTE_VF_MODULE",
-      FLAG_HANDLE_SO_WORKFLOWS: "FLAG_HANDLE_SO_WORKFLOWS"
+      FLAG_HANDLE_SO_WORKFLOWS: "FLAG_HANDLE_SO_WORKFLOWS",
+      FLAG_CREATE_ERROR_REPORTS: "FLAG_CREATE_ERROR_REPORTS"
     }
 
   };
index 0705812..62ef1a4 100755 (executable)
@@ -22,8 +22,8 @@
 (function () {\r
        'use strict';\r
 \r
-       appDS2.controller("ServiceModelController", function ($scope, $http, $location, COMPONENT, VIDCONFIGURATION, FIELD, DataService, vidService,\r
-                       PropertyService, UtilityService, AsdcService,$timeout) {\r
+       appDS2.controller("ServiceModelController",function ($uibModal, $scope, $http, $location, COMPONENT, VIDCONFIGURATION, FIELD, DataService, vidService,\r
+                       PropertyService, UtilityService, AsdcService, $timeout, featureFlags) {\r
 \r
                $scope.popup = {};\r
                var defaultViewPerPage = 10;\r
                        $scope.currentPage++;\r
                };\r
 \r
+               $scope.showReportWindow = function() {\r
 \r
+                       const modalWindow = $uibModal.open({\r
+                               templateUrl: 'app/vid/scripts/modals/report-modal/report-modal.html',\r
+                               controller: 'reportModalController',\r
+                               controllerAs: 'vm',\r
+                               resolve: {\r
+                                       errorMsg: function () {\r
+                                               return $scope.status;\r
+                                       }\r
+                               }\r
+                       });\r
+\r
+               };\r
+\r
+               $scope.isShowErrorReport = function() {\r
+                       return featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_CREATE_ERROR_REPORTS);\r
+               };\r
                \r
                $scope.createType = COMPONENT.A_LA_CARTE;\r
                $scope.deployService = function(service) {\r
index 16ec01d..1912518 100755 (executable)
 appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", "DataService", "PropertyService", "$scope", "$http", "$timeout", "$location", "$log", "$route", "$uibModal", "VIDCONFIGURATION", "UtilityService", "vidService", "AaiService", "MsoService", "OwningEntityService", "AsdcService","featureFlags", "$q", "_",\r
     function (COMPONENT, FIELD, PARAMETER, DataService, PropertyService, $scope, $http, $timeout, $location, $log, $route, $uibModal, VIDCONFIGURATION, UtilityService, vidService, AaiService, MsoService, OwningEntityService, AsdcService, featureFlags, $q, _) {\r
 \r
+        $scope.showReportWindow = function() {\r
+\r
+            const modalWindow = $uibModal.open({\r
+                templateUrl: 'app/vid/scripts/modals/report-modal/report-modal.html',\r
+                controller: 'reportModalController',\r
+                controllerAs: 'vm',\r
+                resolve: {\r
+                    errorMsg: function () {\r
+                        return $scope.errorMsg;\r
+                    }\r
+                }\r
+            });\r
+        };\r
+\r
         $scope.showVnfDetails = function (vnf) {\r
             console.log("showVnfDetails");\r
             DataService.setVnfInstanceId(COMPONENT.VNF_INSTANCE_ID);\r
@@ -728,6 +742,10 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER",
             return featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_SHOW_VERIFY_SERVICE);\r
         }\r
 \r
+        $scope.isShowErrorReport = function() {\r
+            return featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_CREATE_ERROR_REPORTS);\r
+        }\r
+\r
         $scope.isEnableVerifyService = function () {\r
             //Button should only be enabled when the service type is A la carte\r
             if (DataService.getALaCarte()) {\r
index 57bf54b..1562783 100755 (executable)
 "use strict";\r
 \r
 var creationDialogController = function (COMPONENT, FIELD, PARAMETER, $scope, $http, $timeout, $log,\r
-                                         CreationService, UtilityService, DataService, VIDCONFIGURATION, $location) {\r
+                                         CreationService, UtilityService, DataService, VIDCONFIGURATION, $location, $uibModal, featureFlags) {\r
 \r
     $scope.isDialogVisible = false;\r
+    $scope.isServiceError = false;\r
     $scope.summaryControl = {};\r
     $scope.userProvidedControl = {};\r
 \r
+\r
     var callbackFunction = undefined;\r
     var componentId = undefined;\r
 \r
+    $scope.showReportWindow = function() {\r
+\r
+        let errorMsg;\r
+\r
+        if($scope.error !== undefined && $scope.error != null) {\r
+            errorMsg = $scope.error;\r
+        } else {\r
+            errorMsg = "";\r
+        }\r
+\r
+        const modalWindow = $uibModal.open({\r
+            templateUrl: 'app/vid/scripts/modals/report-modal/report-modal.html',\r
+            controller: 'reportModalController',\r
+            controllerAs: 'vm',\r
+            resolve: {\r
+                errorMsg: function () {\r
+                    return errorMsg;\r
+                }\r
+            }\r
+        });\r
+\r
+        $scope.isDialogVisible = false;\r
+        $scope.popup.isVisible = false;\r
+    };\r
+\r
+    $scope.isShowErrorReport = function() {\r
+        return featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_CREATE_ERROR_REPORTS);\r
+    };\r
+\r
     $scope.shouldShowOldPopup = function () {\r
         return !DataService.getShouldIncludeInAsyncInstantiationFlow();\r
     };\r
@@ -68,6 +99,7 @@ var creationDialogController = function (COMPONENT, FIELD, PARAMETER, $scope, $h
             CreationService.initializeComponent(request.componentId);\r
 \r
             CreationService.setHttpErrorHandler(function (response) {\r
+                $scope.isServiceError = true;\r
                 showError(FIELD.ERROR.SYSTEM_FAILURE, UtilityService\r
                     .getHttpErrorMessage(response));\r
             });\r
@@ -373,4 +405,5 @@ var creationDialogController = function (COMPONENT, FIELD, PARAMETER, $scope, $h
 \r
 appDS2.controller("creationDialogController", ["COMPONENT", "FIELD", "PARAMETER", "$scope", "$http",\r
     "$timeout", "$log", "CreationService", "UtilityService", "DataService", "VIDCONFIGURATION", "$location",\r
+    "$uibModal", "featureFlags",\r
     creationDialogController]);\r
index 9bb439f..a5c0388 100755 (executable)
@@ -63,8 +63,8 @@
  * "$scope.popup".\r
  */\r
 \r
-var msoCommitController = function(COMPONENT, FIELD, $scope, $http, $timeout, $window, $log,\r
-               MsoService, PropertyService, UtilityService, TestEnvironmentsService) {\r
+var msoCommitController = function(COMPONENT, FIELD, $scope, $http, $timeout, $window, $log, $uibModal,\r
+               MsoService, PropertyService, UtilityService, TestEnvironmentsService, DataService) {\r
 \r
        $scope.isViewVisible = false;\r
        $scope.progressBarControl = {};\r
@@ -72,6 +72,29 @@ var msoCommitController = function(COMPONENT, FIELD, $scope, $http, $timeout, $w
     var getRequestStatusFunc = getOrchestrationRequestStatus; //default\r
        var _this = this;\r
 \r
+       $scope.showReportWindow = function() {\r
+               let requestInfo = {};\r
+               requestInfo.requestId = _this.requestId;\r
+               requestInfo.serviceUuid = $scope.instanceId;\r
+\r
+               const modalWindow = $uibModal.open({\r
+                       templateUrl: 'app/vid/scripts/modals/report-modal/report-modal.html',\r
+                       controller: 'reportModalInstanceController',\r
+                       controllerAs: 'vm',\r
+                       resolve: {\r
+                               errorMsg: function () {\r
+                                       return $scope.log;\r
+                               },\r
+                               requestInfo: function () {\r
+                                       return requestInfo;\r
+                               }\r
+                       }\r
+               });\r
+\r
+               $scope.isViewVisible = false;\r
+               $scope.popup.isVisible = false;\r
+       };\r
+\r
        $scope.$on("createInstance", function(event, request) {\r
                init(request, COMPONENT.MSO_CREATE_REQ, getOrchestrationRequestStatus );\r
                MsoService.createInstance(request, handleInitialResponse);\r
@@ -318,5 +341,5 @@ var msoCommitController = function(COMPONENT, FIELD, $scope, $http, $timeout, $w
 }\r
 \r
 appDS2.controller("msoCommitController", [ "COMPONENT", "FIELD", "$scope", "$http", "$timeout",\r
-               "$window", "$log", "MsoService", "PropertyService", "UtilityService", "TestEnvironmentsService",\r
+               "$window", "$log", "$uibModal", "MsoService", "PropertyService", "UtilityService", "TestEnvironmentsService", "DataService",\r
                msoCommitController ]);\r
index 2eaa751..eea501f 100644 (file)
 
     function newChangeManagementModalController($uibModalInstance, $uibModal,$q, AaiService, changeManagementService, Upload, $log, $scope, _, COMPONENT, VIDCONFIGURATION, DataService, featureFlags) {
 
+
         var vm = this;
         vm.hasScheduler = !!VIDCONFIGURATION.SCHEDULER_PORTAL_URL;
+        vm.errorMsg='';
 
         vm.wizardStep = 1;
         vm.nextStep = function(){
 
         var attuid;
 
+        $scope.showReportWindow = function() {
+            const modalWindow = $uibModal.open({
+                templateUrl: 'app/vid/scripts/modals/report-modal/report-modal.html',
+                controller: 'reportModalController',
+                controllerAs: 'vm',
+                resolve: {
+                    errorMsg: function () {
+                        return vm.errorMsg.message;
+                    }
+                }
+            });
+
+        };
+
+        $scope.isShowErrorReport = function() {
+            return featureFlags.isOn(COMPONENT.FEATURE_FLAGS.FLAG_CREATE_ERROR_REPORTS);
+        };
+
         function fetchAttUid() {
             var defer = $q.defer();
             if (attuid) {
@@ -54,6 +74,7 @@
                     },
                     function (err) {
                         defer.reject(err);
+                        vm.errorMsg = err;
                     });
             }
             return defer.promise;
@@ -75,6 +96,7 @@
                 })
                 .catch(function (error) {
                     $log.error(error);
+                    vm.errorMsg = err;
                 })
         };
 
                                     newVNFName.availableVersions = _.sortBy(_.uniq(versions, response.data.service, true),"modelInfo.modelVersion");
                                 }).catch(function (error) {
                                 $log.error(error);
+                                vm.errorMsg = error;
                             });
                         });
                     }
                 }
                                }catch(err){
                                        $log.error('SchedulerCtrl::extractChangeManagementCallbackDataStr error: ' + err);
+                                       vm.errorMsg = err;
                                }
 
                                result.requestDetails.push(data);
                 })
                 .catch(function (error) {
                     $log.error(error);
+                    vm.errorMsg = error;
                 });
         };
 
                     })
                     .catch(function (error) {
                         reject(error);
+                        vm.errorMsg = error;
                     });
             });
         }
             vm.localWorkflows = response.data.workflows || [];
           }).catch(function (error) {
             $log.error(error);
+            vm.errorMsg = error;
           });
         };
 
             vm.remoteWorkflows = response.data || [];
           }).catch(function (error) {
             $log.error(error);
+            vm.errorMsg = error;
           });
         };
 
           })
           .catch(function (error) {
             $log.error(error);
+            vm.errorMsg = error;
           });
         };
 
                         vnfName[0].selectedFile = JSON.parse(lines);
                     } catch (error) {
                         $log.error(error);
+                        vm.errorMsg = error;
                     }
                 };
                 fileReader.readAsText(file);
index 611b8e5..7ccddba 100644 (file)
@@ -22,6 +22,7 @@
 <div class="modal-header">
     <h3 class="modal-title" id="modal-title">New VNF Change</h3>
     <span ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+    <div ng-if="vm.errorMsg!==''"><font color='red'>{{vm.errorMsg.message}}</font></div>
 </div>
 <form class="form-create" name="newChangeManagement" ng-submit="vm.openModal();vm.close();" novalidate>
     <div class="modal-body step1" ng-show="vm.wizardStep === 1" >
             <button type="button" id="cancel" name="cancel" class="btn btn-white" ng-click="vm.close()">Cancel</button>
             <button ng-if="!vm.isScaleOut() || (vm.isScaleOut() && vm.wizardStep === 2)" type="submit" id="submit" name="submit" class="btn btn-primary" data-ng-disabled="newChangeManagement.$invalid">{{vm.hasScheduler ? "Schedule" : "Confirm"}}</button>
             <button ng-if="vm.isScaleOut() && vm.wizardStep === 1" ng-click="vm.nextStep();" type="button" id="next" name="next" class="btn btn-primary" data-ng-disabled="newChangeManagement.$invalid">Next</button>
+            <button ng-if="isShowErrorReport() && vm.errorMsg!==''" ng-click="showReportWindow()" type="button" class="btn btn-danger" >Create report</button>
         </div>
     </div>
 </form>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal-request.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal-request.controller.js
new file mode 100644 (file)
index 0000000..bee3a4c
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+(function () {
+    'use strict';
+
+    appDS2.controller("reportModalInstanceController", ["$uibModalInstance", "$scope", "$window", "ReportService", "errorMsg", "requestInfo", reportModalInstanceController]);
+
+    function reportModalInstanceController($uibModalInstance, $scope, $window, ReportService, errorMsg, requestInfo) {
+        const vm = this;
+
+        const init = function() {
+            vm.timestamp =  ReportService.getReportTimeStamp();
+            vm.downloadEnable = false;
+            ReportService.getReportData(requestInfo).then(
+                response => {
+                    vm.saveReportData(response);
+                }, response => {
+                    vm.printReportFail(response);
+                });
+        };
+
+        vm.saveReportData = function(response) {
+            vm.report = errorMsg + "\n\n Collected data from API:\n" + JSON.stringify(response.data,  null, "\t") ;
+
+            const blob = new Blob([ vm.report ], { type : 'text/plain' });
+            vm.download = ($window.URL || $window.webkitURL).createObjectURL( blob );
+            vm.downloadEnable = true;
+        };
+
+        vm.printReportFail = function(response) {
+            vm.downloadEnable = false;
+            vm.report = errorMsg + "\n\n API error:\n" + JSON.stringify(response.data,  null, "\t") ;
+        };
+
+
+        vm.close = function () {
+            $uibModalInstance.close();
+        };
+
+        vm.ok = function () {
+            $uibModalInstance.close(true);
+        };
+
+        init();
+    }
+})();
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal-request.controller.test.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal-request.controller.test.js
new file mode 100644 (file)
index 0000000..87edca3
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+require('./report-modal-request.controller');
+const jestMock = require('jest-mock');
+
+describe('Testing error report creation', () => {
+    let $notNeeded;
+    let $controller;
+
+    let mockHttp;
+
+    let mockModalInstance;
+    let mockWindow;
+    let mockReportService;
+    let testErrorMsg;
+
+    let correctResponse;
+    let failResponse;
+
+    let mockInfo;
+
+    beforeEach(
+        angular.mock.module('app')
+    );
+
+    beforeEach(inject(function (_$controller_) {
+        $notNeeded = jestMock.fn();
+        mockHttp = jestMock.fn();
+
+        mockModalInstance = {};
+        mockWindow = {
+            webkitURL: {
+                createObjectURL: function (blob) {
+                    return blob;
+                }
+            }
+        };
+
+        correctResponse = {data:{report:"test-error-report",status:202}};
+        failResponse = {data:{report:"test-fail-report",status:404}};
+
+        mockReportService = {
+
+            getReportData: function(info) {
+                return Promise.resolve(correctResponse);
+            },
+            getReportTimeStamp: function () {
+                return "testTime";
+            }
+        };
+
+        testErrorMsg = 'testing message';
+
+        $controller = _$controller_('reportModalInstanceController',{
+            $uibModalInstance: mockModalInstance,
+            $scope: $notNeeded,
+            $window: mockWindow,
+            ReportService: mockReportService,
+            errorMsg: testErrorMsg,
+            requestInfo: mockInfo
+        });
+    }));
+
+    test('Verify close will call close in modal instance', () => {
+        mockModalInstance.close = jestMock.fn();
+
+        $controller.close();
+
+        expect(mockModalInstance.close).toHaveBeenCalled();
+    });
+
+    test('Verify report was constructed properly', () => {
+
+        $controller.saveReportData(correctResponse);
+
+        expect($controller.report).toEqual(testErrorMsg + "\n\n Collected data from API:\n" + JSON.stringify(correctResponse.data,  null, "\t"));
+        expect($controller.downloadEnable).toBeTruthy();
+        expect($controller.download).toEqual(new Blob([ $controller.report ], { type : 'text/plain' }));
+    });
+
+    test('Verify report contains error if API did not respond', () => {
+
+        $controller.printReportFail(failResponse);
+
+        expect($controller.report).toEqual(testErrorMsg + "\n\n API error:\n" + JSON.stringify(failResponse.data,  null, "\t"));
+        expect($controller.downloadEnable).toBeFalsy();
+    });
+
+});
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.controller.js
new file mode 100644 (file)
index 0000000..6ec5c41
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+(function () {
+    'use strict';
+
+    appDS2.controller("reportModalController", ["$uibModalInstance", "$scope", "$window", "ReportService", "errorMsg", reportModalController]);
+
+    function reportModalController($uibModalInstance, $scope, $window, ReportService, errorMsg) {
+        const vm = this;
+
+        const init = function() {
+            vm.timestamp =  ReportService.getReportTimeStamp();
+            vm.downloadEnable = false;
+            ReportService.getReportData({}).then(
+                response => {
+                    vm.saveReportData(response);
+                }, response => {
+                    vm.printReportFail(response);
+                });
+        };
+
+        vm.saveReportData = function(response) {
+            vm.report = errorMsg + "\n\n Collected data from API:\n" + JSON.stringify(response.data,  null, "\t") ;
+
+            const blob = new Blob([ vm.report ], { type : 'text/plain' });
+            vm.download = ($window.URL || $window.webkitURL).createObjectURL( blob );
+            vm.downloadEnable = true;
+        };
+
+        vm.printReportFail = function(response) {
+            vm.downloadEnable = false;
+            vm.report = errorMsg + "\n\n API error:\n" + JSON.stringify(response.data,  null, "\t") ;
+        };
+
+        vm.close = function () {
+            $uibModalInstance.close();
+        };
+
+        vm.ok = function () {
+            $uibModalInstance.close(true);
+        };
+
+        init();
+    }
+})();
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.controller.test.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.controller.test.js
new file mode 100644 (file)
index 0000000..da834ba
--- /dev/null
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+require('./report-modal.controller');
+const jestMock = require('jest-mock');
+
+describe('Testing error report creation', () => {
+    let $notNeeded;
+    let $controller;
+
+    let mockHttp;
+
+    let mockModalInstance;
+    let mockWindow;
+    let mockReportService;
+    let testErrorMsg;
+
+    let correctResponse;
+    let failResponse;
+
+    beforeEach(
+        angular.mock.module('app')
+    );
+
+    beforeEach(inject(function (_$controller_) {
+        $notNeeded = jestMock.fn();
+        mockHttp = jestMock.fn();
+
+        mockModalInstance = {};
+        mockWindow = {
+            webkitURL: {
+                    createObjectURL: function (blob) {
+                        return blob;
+                }
+            }
+        };
+
+        correctResponse = {data:{report:"test-error-report",status:202}};
+        failResponse = {data:{report:"test-fail-report",status:404}};
+
+        mockReportService = {
+
+            getReportData: function() {
+                return Promise.resolve(correctResponse);
+            },
+            getReportTimeStamp: function () {
+                return "testTime";
+            }
+        };
+
+        testErrorMsg = 'testing message';
+
+        $controller = _$controller_('reportModalController',{
+            $uibModalInstance: mockModalInstance,
+            $scope: $notNeeded,
+            $window: mockWindow,
+            ReportService: mockReportService,
+            errorMsg: testErrorMsg
+        });
+    }));
+
+    test('Verify close will call close in modal instance', () => {
+        mockModalInstance.close = jestMock.fn();
+
+        $controller.close();
+
+        expect(mockModalInstance.close).toHaveBeenCalled();
+    });
+
+    test('Verify report was constructed properly', () => {
+
+        $controller.saveReportData(correctResponse);
+
+        expect($controller.report).toEqual(testErrorMsg + "\n\n Collected data from API:\n" + JSON.stringify(correctResponse.data,  null, "\t"));
+        expect($controller.downloadEnable).toBeTruthy();
+        expect($controller.download).toEqual(new Blob([ $controller.report ], { type : 'text/plain' }));
+    });
+
+    test('Verify report contains error if API did not respond', () => {
+
+        $controller.printReportFail(failResponse);
+
+        expect($controller.report).toEqual(testErrorMsg + "\n\n API error:\n" + JSON.stringify(failResponse.data,  null, "\t"));
+        expect($controller.downloadEnable).toBeFalsy();
+    });
+
+});
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.css
new file mode 100644 (file)
index 0000000..77b9354
--- /dev/null
@@ -0,0 +1,4 @@
+.download-button{
+    text-decoration: none !important;
+    text-underline: none;
+}
\ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/report-modal/report-modal.html
new file mode 100644 (file)
index 0000000..58e4c49
--- /dev/null
@@ -0,0 +1,35 @@
+<!--
+  ============LICENSE_START=======================================================
+  VID
+  ================================================================================
+  Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+
+<link rel="stylesheet" type="text/css" href="app/vid/styles/modals.css">
+<link rel="stylesheet" type="text/css" href="app/vid/styles/modal-create-new.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/report-modal/report-modal.css" />
+
+<div class="modal-header">
+    <h3 id="modal-title">Error report</h3>
+</div>
+<div class="modal-body">
+    <textarea style="height: 500px">{{vm.report}}</textarea>
+</div>
+<div class="modal-footer">
+    <a ngx-enabled="{{vm.downloadEnable}}" att-button download="VID_fault_report_{{vm.timestamp}}.txt" ng-href="{{vm.download}}" btn-type="primary" size="small" class="download-button" >Download report</a>
+    <button type="button" data-tests-id="cancelButton" ng-click="vm.close();" att-button
+            btn-type="primary" size="small" >Close</button>
+</div>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/reportService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/reportService.js
new file mode 100644 (file)
index 0000000..0b401dc
--- /dev/null
@@ -0,0 +1,27 @@
+"use strict";
+
+var ReportService = function ( $http ) {
+
+    return {
+
+        getReportData: function(requestInfo) {
+            return $http.post("error-report",requestInfo);
+        },
+
+        getReportTimeStamp: function () {
+            const today = new Date();
+            const se = String(today.getSeconds()).padStart(2, '0');
+            const mi = String(today.getMinutes()).padStart(2, '0');
+            const hr = String(today.getHours()).padStart(2, '0');
+            const dd = String(today.getDate()).padStart(2, '0');
+            const mm = String(today.getMonth() + 1).padStart(2, '0');
+            const yyyy = today.getFullYear();
+
+            return hr + '-' + mi + '-' + se + "_" + dd + '-' + mm + '-' + yyyy;
+        }
+
+    }
+
+};
+
+appDS2.factory("ReportService", ["$http", ReportService]);
\ No newline at end of file
index 3597e57..ba9960f 100755 (executable)
@@ -29,7 +29,8 @@
             <label>Status:</label><span class="status">{{status}}</span>\r
         </div>\r
 \r
-        <div ng-if="errorMsg != null"><font color='red'>{{errorMsg}}\r
+        <div ng-if="errorMsg != null"><font color='red'>{{errorMsg}}<br/>\r
+            <button class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">create report</button>\r
             <pre>{{errorDetails | json}}</pre>\r
         </font></div>\r
 \r
index 2d04067..7081fdb 100755 (executable)
@@ -29,7 +29,8 @@
             <label>Status:</label><span class="status">{{status}}</span>\r
         </div>\r
 \r
-        <div ng-if="errorMsg != null"><font color='red'>{{errorMsg}}\r
+        <div ng-if="errorMsg != null"><font color='red'>{{errorMsg}}<br/>\r
+            <button class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">create report</button>\r
             <pre>{{errorDetails | json}}</pre>\r
         </font></div>\r
 \r
index cc69fb5..68aaec5 100755 (executable)
                        <img src="app/vid/images/spinner.gif"></img>\r
                        <label>Status:</label><span class="status">{{status}}</span>\r
                </div>\r
-               <div ng-if="errorMsg != null"><font color='red'>{{errorMsg}}<pre>{{errorDetails | json}}</pre></font></div>\r
+               <div ng-if="errorMsg != null">\r
+                       <font color='red'>{{errorMsg}}<br/>\r
+                       <button class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">Create report</button>\r
+                       <pre>{{errorDetails | json}}</pre></font>\r
+               </div>\r
                <h2 class="heading2"><center>Create New Service Instance</center></h2>\r
                \r
                <table class="create-instance-service ">\r
index 6c2dfc6..4b9f8b0 100755 (executable)
                                <label>Status:</label><span class="status">{{status}}</span>\r
                        </div>\r
 \r
-                       <div data-tests-id="subDetailsErrMsg" ng-if="errorMsg != null"><font color='red'>{{errorMsg}}<pre>{{errorDetails | json}}</pre></font></div>\r
+                       <div data-tests-id="subDetailsErrMsg" ng-if="errorMsg != null">\r
+                               <font color='red'>{{errorMsg}}<pre>{{errorDetails | json}}</pre></font>\r
+                               <button class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">Create report</button>\r
+                       </div>\r
        \r
                         <h1 class="heading1"><center>Subscriber Details for {{selectedSubscriberId}} ({{selectedSubscriberName}})</center></h1>\r
                        <br>\r
index 158c831..0e0bb94 100755 (executable)
         <div ng-include="'app/vid/scripts/view-models/detailsDialog.htm'"></div>\r
     </div>\r
 \r
+    <div ng-if="errorMsg != null">\r
+        <font color='red'>{{errorMsg}}<br/>\r
+            <button class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">Create report</button>\r
+            <pre>{{errorDetails | json}}</pre>\r
+        </font>\r
+    </div>\r
+\r
     <div>\r
         <div class="statusLine">\r
             <img src="app/vid/images/spinner.gif"\r
index 819f79d..4aa37c9 100755 (executable)
                        <img src="app/vid/images/spinner.gif"></img>\r
                        </span>\r
                        <span class="statusLine" ng-class="{true:'progVisible', false:'progHidden'}[isProgressVisible]">\r
-                       <label>Status:</label><span class="status"><span ng-show="error"><font color='red'><b>Error: </b></font></span>{{status}}</span>\r
+                       <label>Status:</label><span class="status">\r
+                               <span ng-show="error"><font color='red'><b>Error: </b></font>{{status}}<br/>\r
+                               <button class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">Create report</button>\r
+                               </span>\r
+                       </span>\r
+\r
                </span>\r
        <br><br>\r
        \r
index 75f6b68..49d3ef8 100755 (executable)
                        </div>\r
                        <div class="buttonRow">\r
                                <button data-tests-id="confirmButton" ngx-enabled="{{isConfirmEnabled}}" att-button size="small"\r
-                                       ng-click="confirm();">Confirm</button>\r
+                                               ng-click="confirm();">Confirm</button>\r
                                <button type="button" data-tests-id="cancelButton" ng-click="cancel();" att-button\r
-                                       btn-type="primary" size="small">Cancel</button>\r
+                                               btn-type="primary" size="small">Cancel</button>\r
+                               <button class="btn-danger" ng-if="isShowErrorReport() && isServiceError" att-button size="small"\r
+                                               ng-click="showReportWindow()">Create report</button>\r
                        </div>\r
                </div>\r
        </div>\r
index 14851f9..1017924 100755 (executable)
@@ -43,6 +43,8 @@
        <div class="buttonRow">\r
                <button data-tests-id="msoCommitDialogCloseButton" ngx-enabled="{{isCloseEnabled}}" att-button size="small"\r
                        ng-click="close();">Close</button>\r
+               <button class="btn-danger" att-button size="small" ng-show="!isProgressVisible"\r
+                               ng-click="showReportWindow()">Create report</button>\r
        </div>\r
 </div>\r
-</div>\r
+</div>
\ No newline at end of file
index 06cccfc..4570a0b 100755 (executable)
@@ -30,7 +30,9 @@
                        <img src="app/vid/images/spinner.gif"></img>\r
                        </span>\r
                        <span class="statusLine" ng-class="{true:'progVisible', false:'progHidden'}[isProgressVisible]">\r
-                       <label>Status:</label><span class="status"><span ng-show="error"><font color='red'><b>Error: </b></font></span>{{status}}</span>\r
+                       <label>Status:</label><span class="status"><span ng-show="error"><font color='red'><b>Error: </b></font></span>{{status}} <br/>\r
+                       <button ng-show="error" class="btn btn-danger" ng-click="showReportWindow()" ng-if="isShowErrorReport()">create report</button>\r
+                       </span>\r
                </span>\r
        <br><br>\r
 \r