Yangman - requests settings
[dlux.git] / modules / yangman-resources / src / main / resources / yangman / controllers / request-header.controller.js
1 define([
2     'app/yangman/controllers/params-admin.controller',
3     'app/yangman/services/time-tracking.services',
4 ], function (ParamsAdminCtrl) {
5     'use strict';
6
7     angular.module('app.yangman').controller('RequestHeaderCtrl', RequestHeaderCtrl);
8
9     RequestHeaderCtrl.$inject = [
10         '$timeout', '$mdDialog', '$mdToast', '$scope', '$rootScope', 'ENV', 'YangmanService', 'ParametersService',
11         'PathUtilsService', 'RequestsService', '$filter', 'DataBackupService', 'constants', 'TimeTrackingService'
12     ];
13
14     function RequestHeaderCtrl($timeout, $mdDialog, $mdToast, $scope, $rootScope, ENV, YangmanService, ParametersService,
15                                PathUtilsService, RequestService, $filter, DataBackupService, constants,
16                                TimeTrackingService) {
17         var requestHeader = this;
18
19         requestHeader.allOperations = [constants.OPERATION_GET, constants.OPERATION_POST, constants.OPERATION_PUT, constants.OPERATION_DELETE];
20         requestHeader.constants = constants;
21         requestHeader.urlChanged = false;
22         requestHeader.executedOperation = null;
23         requestHeader.selectedOperationsList = [];
24         requestHeader.selectedOperation = null;
25         requestHeader.requestUrl = '';
26         requestHeader.selectedPluginsButtons = [];
27         requestHeader.selectedPlugin = null;
28         requestHeader.statusObj = null;
29         requestHeader.fillFormWithReceivedData = true;
30
31         // methods
32         requestHeader.executeOperation = executeOperation;
33         requestHeader.executePluginFunctionality = executePluginFunctionality;
34         requestHeader.fillNodeData = fillNodeData;
35         requestHeader.changeDataType = changeDataType;
36         requestHeader.prepareDataAndExecute = prepareDataAndExecute;
37         requestHeader.initMountPoint = initMountPoint;
38         requestHeader.setJsonView = setJsonView;
39         requestHeader.setRequestUrl = setRequestUrl;
40         requestHeader.showParamsAdmin = showParamsAdmin;
41         requestHeader.saveRequestToCollection = saveRequestToCollection;
42         requestHeader.unsetPluginFunctionality = unsetPluginFunctionality;
43
44         $scope.$on(constants.YANGMAN_CHANGE_TO_JSON, function () {
45             sendRequestData($scope.buildRootRequest(), 'SENT');
46         });
47         /**
48          * Set selected operations based on data store
49          */
50         $scope.$on(constants.SET_SEL_OPERATIONS, function (event, operations, setUrl) {
51             setAllowedMethods(operations);
52
53             if ( setUrl ) {
54                 setRequestUrl();
55             }
56         });
57
58         /**
59          * Watching for changes in shown detail data type (radio button)
60          */
61         $scope.$on(constants.YANGMAN_HEADER_INIT, function (event, args) {
62             init();
63             setRequestUrl(args.params.path);
64             setRequestMethod(args.params.method);
65             setRequestStatus(args.params.statusObj);
66             setJsonView();
67             (args.cbk || angular.noop)();
68         });
69
70         $scope.$on(constants.YANGMAN_FILL_NODE_FROM_REQ, function (event, args) {
71             setNodeDataFromRequestData(args.params.requestUrl, args.params.leftpanel);
72             (args.cbk || angular.noop)();
73         });
74
75         $scope.$on(constants.YANGMAN_EXECUTE_WITH_DATA, function (event, args) {
76             executeOperation(args.params.data ? angular.fromJson(args.params.data) : {}, args.cbk);
77         });
78
79         init();
80
81         /**
82          * Setter for selected operation
83          * @param method
84          */
85         function setRequestMethod(method){
86             requestHeader.selectedOperation = method;
87         }
88
89         /**
90          * Setter for request status
91          * @param statusObj
92          */
93         function setRequestStatus(statusObj){
94             requestHeader.statusObj = statusObj;
95         }
96
97         /**
98          * Show popup for parameters administration
99          * @param event
100          */
101         function showParamsAdmin(event) {
102             $mdDialog.show({
103                 controller: ParamsAdminCtrl,
104                 controllerAs: 'paramsAdmin',
105                 templateUrl: $scope.globalViewPath + 'popup/parameters-admin.tpl.html',
106                 parent: angular.element('#yangmanModule'),
107                 targetEvent: event,
108                 clickOutsideToClose: true,
109                 locals: {
110                     parametersList: $scope.parametersList,
111                 },
112             }).then(
113                 function (){
114                     $scope.parametersList.loadListFromStorage();
115                 },
116                 function (){
117                     $scope.parametersList.loadListFromStorage();
118                 }
119             );
120         }
121
122         /**
123          * Method for selecting correct json view by selected operation
124          */
125         function setJsonView(){
126             var both = [constants.OPERATION_PUT, constants.OPERATION_POST];
127
128             if ( both.indexOf(requestHeader.selectedOperation) > -1 ){
129                 $scope.setJsonView(true, true);
130             } else {
131                 $scope.setJsonView(true, false);
132             }
133         }
134
135         /**
136          * Change displayed data type to json or form, after switching set current data to be displayed
137          */
138         function changeDataType(){
139             $scope.switchSection('rightPanelSection', requestHeader.selectedShownDataType);
140
141             if (!$scope.node || requestHeader.urlChanged) {
142                 requestHeader.setRequestUrl();
143                 requestHeader.urlChanged = false;
144             }
145
146             // if changing to json, fill codemirror data
147             if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA && $scope.node ){
148                 setJsonView();
149                 sendRequestData($scope.buildRootRequest(), 'SENT');
150             }
151
152             // if changing to form, try to fill node data
153             if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM) {
154                 var reqData = {};
155
156                 reqData = getDataForForm();
157                 setNodeDataFromRequestData(requestHeader.requestUrl);
158
159                 if ( $scope.node ) {
160
161                     YangmanService.fillNodeFromResponse($scope.node, reqData);
162                     $scope.node.expanded = true;
163                 }
164             }
165         }
166
167         /**
168          * Helper method for building correct json data for form, rpc included
169          * @returns {*}
170          */
171         function getDataForForm(){
172             var params = {
173                     reqData: null,
174                 },
175                 dataTypeFunc = {
176                     rpc: function () {
177                         var sentData = { reqData: null },
178                             allData = { sent: null, received: null };
179
180                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_RECEIVED, params);
181                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, sentData);
182
183                         allData.sent = sentData.reqData ? angular.fromJson(sentData.reqData) : {};
184                         allData.received = params.reqData ? angular.fromJson(params.reqData) : {};
185
186                         return YangmanService.prepareReceivedData(
187                             $scope.node,
188                             requestHeader.selectedOperation,
189                             allData.received,
190                             allData.sent,
191                             requestHeader.selectedShownDataType
192                         );
193                     },
194                     default: function (){
195                         var dataType;
196                         if(requestHeader.executedOperation) {
197                             dataType = requestHeader.executedOperation === constants.OPERATION_GET ? constants.REQUEST_DATA_TYPE_RECEIVED : 'SENT';
198                         }
199                         else {
200                             dataType = requestHeader.selectedOperation === constants.OPERATION_GET ? constants.REQUEST_DATA_TYPE_RECEIVED : 'SENT';
201                         }
202
203                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA + dataType, params);
204                         return params.reqData ? angular.fromJson(params.reqData) : {};
205                     },
206                 };
207
208             return $scope.node ? (dataTypeFunc[$scope.node.type] || dataTypeFunc.default)() : {};
209         }
210
211         /**
212          * Send data to codemirror
213          * @param data
214          */
215         function sendRequestData(data, type){
216             $scope.rootBroadcast(
217                 constants.YANGMAN_SET_CODEMIRROR_DATA + type,
218                 { data: data instanceof Object ? JSON.stringify(data, null, 4) : data }
219             );
220         }
221
222         /**
223          * Set error data to be shown in form area
224          * @param response
225          */
226         function sendErrorData(response) {
227             $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_DATA, response);
228         }
229
230         /**
231          * Create empty parameters list, load from local storage and set to $scope
232          */
233         function initParams(){
234             $scope.parametersList.loadListFromStorage();
235         }
236
237         /**
238          * Initialization
239          */
240         function init(){
241             setAllowedMethods(requestHeader.allOperations);
242             initParams();
243             requestHeader.selectedShownDataType = $scope.rightPanelSection;
244         }
245
246         /**
247          * Set allowed operations for request
248          * @param operations
249          */
250         function setAllowedMethods(operations){
251             requestHeader.selectedOperationsList = operations.length ? operations : requestHeader.allOperations;
252             if (operations.indexOf(requestHeader.selectedOperation) === -1){
253                 requestHeader.selectedOperation = requestHeader.selectedOperationsList[0];
254             }
255         }
256
257         /**
258          * Set header request url if json selected
259          */
260         function setRequestUrl(path){
261             requestHeader.requestUrl = path || ($scope.selectedSubApi ?
262                     ENV.getBaseURL('MD_SAL') + '/restconf/' + $scope.selectedSubApi.buildApiRequestString() : '');
263         }
264
265
266         /**
267          * Try to set api, module, dataStore and node, if api indexes for request url available
268          * and set (or unset) module detail panel to be displayed
269          * @param requestUrl url to try to find
270          * @param leftpanel index of main left tabs to be displayed (we dont want to display module detail in all cases)
271          */
272         function setNodeDataFromRequestData(requestUrl, leftpanel){
273
274             setApiByUrl(requestUrl, function (treeApis) {
275                 // set module
276                 $scope.setModule($filter('filter')(treeApis, { label: $scope.selectedApi.module })[0]);
277
278                 // set datastore
279                 $scope.setDataStore(
280                     $filter('filter')(
281                         $scope.selectedModule.children,
282                         { label: $scope.selectedSubApi.storage })[0],
283                     true,
284                     leftpanel
285                 );
286
287                 // set node
288                 $scope.setNode($scope.selectedSubApi.node);
289
290                 // fill subapi path
291                 PathUtilsService.fillPath($scope.selectedSubApi.pathArray, requestUrl);
292                 setRequestUrl();
293             });
294         }
295
296         /**
297          * Try to set current (depending on url) selectedApi and selectedSubApi to $scope if it exists in api tree data
298          * @param url
299          * @param cbk
300          * @param fill
301          */
302         function setApiByUrl(url, cbk, fill){
303             $scope.rootBroadcast(constants.YANGMAN_GET_API_TREE_DATA, null, function (treeApis) {
304                 var apisIndexes =
305                     PathUtilsService.searchNodeByPath(url, treeApis, null, true, true);
306
307                 if ( apisIndexes ) {
308
309                     // set apis
310                     $scope.setApi(
311                         $scope.apis[apisIndexes.indexApi],
312                         $scope.apis[apisIndexes.indexApi].subApis[apisIndexes.indexSubApi]
313                     );
314
315                     if ( $scope.selectedSubApi && fill ) {
316                         var updatedUrl = YangmanService.cutUrl(url);
317                         PathUtilsService.fillPath($scope.selectedSubApi.pathArray, updatedUrl);
318
319                     }
320
321                     (cbk || angular.noop)(treeApis);
322                 }
323             });
324         }
325
326         function saveRequestToCollection(event) {
327             var historyReq = null,
328                 sentData = { reqData: null },
329                 receivedData = { reqData: null };
330
331             if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM) {
332                 requestHeader.setRequestUrl();
333             }
334
335             historyReq = RequestService.createHistoryRequest(
336                 null, null, requestHeader.requestUrl, requestHeader.selectedOperation, '', '', ''
337             );
338
339             $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, sentData);
340             $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_RECEIVED, receivedData);
341
342             RequestService.fillRequestByMethod(
343                 historyReq, sentData, receivedData, requestHeader.selectedOperation, $scope.node,
344                 requestHeader.selectedShownDataType
345             );
346
347             $scope.rootBroadcast(constants.YANGMAN_SAVE_REQUEST_TO_COLLECTION, { event: event, reqObj: historyReq });
348         }
349
350         function showRequestProgress(){
351             $scope.rootBroadcast(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_START);
352         }
353
354
355         /**
356          * Stop showing progressbar
357          * @param message
358          */
359         function finishRequestProgress(message){
360             $scope.rootBroadcast(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_STOP);
361         }
362
363         /**
364          * Execute request operation
365          */
366         function executeOperation(requestData, executeCbk){
367             TimeTrackingService.startTimer();
368             var allowExecuteOperation =
369                     requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM && $scope.selectedSubApi ?
370                         !PathUtilsService.checkEmptyIdentifiers($scope.selectedSubApi.pathArray) : true;
371
372
373             if ( allowExecuteOperation ) {
374
375                 showRequestProgress();
376                 $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_MESSAGE, '');
377
378                 setRequestUrl(
379                     requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ?
380                         requestHeader.requestUrl :
381                         null
382                 );
383                 if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ){
384                     setApiByUrl(requestHeader.requestUrl, null, true);
385                 }
386
387                 var historyReq = RequestService.createHistoryRequest(
388                     null,
389                     null,
390                     requestHeader.requestUrl,
391                     requestHeader.selectedOperation,
392                     '', '', ''
393                 );
394
395                 YangmanService.executeRequestOperation(
396                     $scope.selectedApi,
397                     $scope.selectedSubApi,
398                     requestHeader.selectedOperation,
399                     $scope.node,
400                     requestHeader.selectedShownDataType,
401                     requestHeader.requestUrl,
402                     requestData,
403                     $scope.parametersList,
404                     executeReqSuccCbk,
405                     executeReqErrCbk
406                 );
407                 requestHeader.executedOperation = requestHeader.selectedOperation;
408             } else {
409                 $scope.rootBroadcast(
410                     constants.YANGMAN_SET_ERROR_MESSAGE,
411                     $filter('translate')(constants.YANGMAN_ERROR_EMPTY_IDENTIFIERS)
412                 );
413                 finishRequestProgress();
414             }
415
416             /**
417              * Success callback after executin operation
418              * @param reqInfo
419              * @param response
420              */
421             function executeReqSuccCbk(reqInfo, response) {
422
423                 var preparedReceivedData = {};
424
425                 if (requestHeader.fillFormWithReceivedData) {
426                     preparedReceivedData = YangmanService.prepareReceivedData(
427                         $scope.node,
428                         requestHeader.selectedOperation,
429                         response.data ? response.data.plain() : {},
430                         reqInfo.requestSrcData,
431                         requestHeader.selectedShownDataType
432                     );
433                 }
434
435                 finishRequestProgress();
436
437                 requestHeader.statusObj = reqInfo;
438
439                 sendErrorData({});
440
441                 if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA){
442                     setNodeDataFromRequestData(requestHeader.requestUrl);
443                     sendRequestData(preparedReceivedData, constants.REQUEST_DATA_TYPE_RECEIVED);
444                     sendRequestData(reqInfo.requestSrcData || {}, 'SENT');
445                 } else {
446
447                     if ($scope.node && requestHeader.selectedOperation !== constants.OPERATION_DELETE && requestHeader.fillFormWithReceivedData){
448
449                         YangmanService.fillNodeFromResponse($scope.node, preparedReceivedData);
450                         YangmanService.handleNodeIdentifier(
451                             $scope.parametersList, $scope.selectedSubApi, $scope.node
452                         );
453                         $scope.node.expanded = true;
454
455                         $scope.rootBroadcast(constants.YANGMAN_DISABLE_ADDING_LIST_ELEMENT);
456                         preparedReceivedData = YangmanService.checkRpcReceivedData(preparedReceivedData, $scope.node);
457                         sendRequestData(preparedReceivedData, constants.REQUEST_DATA_TYPE_RECEIVED);
458                     }
459                 }
460
461                 // create and set history request
462                 requestHeader.statusObj.time = TimeTrackingService.returnTime();
463
464                 historyReq.setExecutionData(
465                     reqInfo.requestSrcData,
466                     $scope.historySettings.data.saveReceived ? preparedReceivedData : null,
467                     $scope.historySettings.data.saveResponseData ? reqInfo.status : '',
468                     $scope.historySettings.data.saveResponseData ? reqInfo.status : '',
469                     $scope.historySettings.data.saveResponseData ? reqInfo.statusText : '',
470                     $scope.historySettings.data.saveResponseData ? requestHeader.statusObj.time : ''
471                 );
472
473                 $scope.rootBroadcast(constants.YANGMAN_SAVE_EXECUTED_REQUEST, historyReq, function (){
474                     $scope.rootBroadcast(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST);
475                 });
476
477                 (executeCbk || angular.noop)(historyReq);
478
479             }
480
481             /**
482              * Error callback after executin operation
483              * @param reqInfo
484              * @param response
485              */
486             function executeReqErrCbk(reqInfo, response) {
487                 requestHeader.statusObj = reqInfo;
488
489                 finishRequestProgress();
490
491                 requestHeader.statusObj.time = TimeTrackingService.returnTime();
492
493                 historyReq.setExecutionData(
494                     reqInfo.requestSrcData,
495                     $scope.historySettings.data.saveReceived ? response.data : null,
496                     $scope.historySettings.data.saveResponseData ? reqInfo.status : '',
497                     $scope.historySettings.data.saveResponseData ? reqInfo.status : '',
498                     $scope.historySettings.data.saveResponseData ? reqInfo.statusText : '',
499                     $scope.historySettings.data.saveResponseData ? requestHeader.statusObj.time : ''
500                 );
501                 $scope.rootBroadcast(constants.YANGMAN_SAVE_EXECUTED_REQUEST, historyReq, function (){
502                     $scope.rootBroadcast(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST);
503                 });
504
505                 if (response.data) {
506                     // try to fill code mirror editor
507                     sendRequestData(response.data, constants.REQUEST_DATA_TYPE_RECEIVED);
508                     sendErrorData(response.data);
509                 }
510
511                 (executeCbk || angular.noop)(historyReq);
512
513
514             }
515
516         }
517
518         /**
519          * TODO :: description
520          * @param pathElem
521          * @param identifier
522          */
523         function fillNodeData(pathElem, identifier) {
524             if ($scope.selectedSubApi && $scope.selectedSubApi.storage === constants.DATA_STORE_CONFIG &&
525                 $scope.selectedSubApi.pathArray.indexOf(pathElem) === ($scope.selectedSubApi.pathArray.length - 1)) {
526                 PathUtilsService.fillListNode($scope.node, identifier.label, identifier.value);
527             }
528
529             requestHeader.urlChanged = true;
530         }
531
532         /**
533          * Check data before executin operations
534          */
535         function prepareDataAndExecute(cbk){
536             if (requestHeader.statusObj) {
537                 requestHeader.statusObj.statusText = null;
538                 requestHeader.statusObj.time = null;
539             }
540
541
542             showRequestProgress();
543
544             $timeout(prepareData);
545             function prepareData() {
546                 if ( requestHeader.requestUrl.length ) {
547                     if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ) {
548                         // get json data
549                         var params = { reqData: null };
550                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, params);
551                         executeOperation(params.reqData ? angular.fromJson(params.reqData) : {}, cbk);
552                     } else {
553                         executeOperation({}, cbk);
554                     }
555                 }
556             }
557         }
558
559         /**
560          * Mount point initialization
561          * @param mountPointStructure
562          * @param mountPointTreeApis
563          * @param mountPointApis
564          * @param augmentations
565          */
566         function initMountPoint(mountPointTreeApis, mountPointApis, augmentations, reqObj){
567             DataBackupService.storeFromScope(
568                 [
569                     'selectedDatastore', 'node', 'apis',
570                     'selectedApi', 'selectedSubApi', 'augmentations', 'selectedModule',
571                 ],
572                 $scope,
573                 'MAIN_SCOPE'
574             );
575
576             $scope.rootBroadcast(constants.YANGMAN_GET_API_TREE_DATA, null, function (treeApis) {
577                 DataBackupService.storeFromScope(
578                     ['treeApis'],
579                     { treeApis: treeApis },
580                     'MODULES_LIST'
581                 );
582             });
583
584             $scope.setNode(null);
585             $scope.setModule(null);
586             $scope.setGlobalParams(mountPointApis, augmentations);
587             $scope.setDataStore(null);
588             requestHeader.statusObj = reqObj;
589             $scope.rootBroadcast(constants.YANGMAN_SET_API_TREE_DATA, mountPointTreeApis);
590         }
591
592         /**
593          * Executing custom plugin callback
594          * @param customPlugin
595          */
596         function executePluginFunctionality(customPlugin){
597             requestHeader.selectedPlugin = customPlugin;
598             customPlugin.runCallback({ scope: $scope, controller: requestHeader });
599         }
600
601         /**
602          * Unset custom plugin functionality - get back major params from scope
603          */
604         function unsetPluginFunctionality(){
605             if ( requestHeader.selectedPlugin ) {
606                 $scope.unsetPlugin(requestHeader);
607             }
608
609             requestHeader.selectedPlugin = null;
610             requestHeader.selectedPluginsButtons = [];
611         }
612
613     }
614
615 });