Merge "Yangman - fix history requests date, apply params to api"
[dlux.git] / modules / yangman-resources / src / main / resources / yangman / services / yangman.services.js
1 define([], function () {
2     'use strict';
3
4     angular.module('app.yangman').service('YangmanService', YangmanService);
5
6     YangmanService.$inject = [
7         'RequestBuilderService',
8         'YangUtilsService',
9         'YangUtilsRestangularService',
10         'ENV',
11         'ParsingJsonService',
12         'RequestsService',
13
14     ];
15
16     function YangmanService(
17         RequestBuilderService,
18         YangUtilsService,
19         YangUtilsRestangularService,
20         ENV,
21         ParsingJsonService,
22         RequestsService
23     ){
24         var service = {
25             checkRpcReceivedData: checkRpcReceivedData,
26             executeRequestOperation: executeRequestOperation,
27             fillNodeFromResponse: fillNodeFromResponse,
28             getDataStoreIndex: getDataStoreIndex,
29             prepareAllRequestData: prepareAllRequestData,
30             prepareReceivedData: prepareReceivedData,
31             validateFile: validateFile,
32         };
33
34         return service;
35
36         function checkRpcReceivedData(data, node){
37             return node.type === 'rpc' ? cutData(data) : data;
38
39             function cutData(data){
40                 return {
41                     output: data[node.label].output,
42                 };
43             }
44         }
45
46         /**
47          * Prepare request date before filling into node depends on method and node type
48          * @param node
49          * @param method
50          * @param rData
51          * @param sData
52          * @param outputType
53          * @returns {*}
54          */
55         function prepareReceivedData(node, method, rData, sData, outputType){
56             var prepareType = {
57                 rpc: function(){
58
59                     if ( outputType === 'form' ){
60                         var dObj = {};
61                         putIntoObj(rData, dObj, node.label);
62                         putIntoObj(sData[node.label] ? sData[node.label] : sData, dObj, node.label);
63                         return dObj;
64                     } else {
65                         return rData;
66                     }
67
68                     /**
69                      * Put source object into destination object by source properties
70                      * @param sourceObj
71                      * @param destinationObj
72                      */
73                     function putIntoObj(sourceObj, destinationObj, containter){
74                         Object.keys(sourceObj).forEach(function(prop){
75                             destinationObj[containter] = destinationObj[containter] ? destinationObj[containter] : {};
76                             destinationObj[containter][prop] = sourceObj[prop];
77                         });
78                     }
79                 },
80                 default: function (){
81                     var methodType = {
82                         GET: function () {
83                             if ( node ){
84                                 node.clear();
85                             }
86                             return rData;
87                         },
88                         DELETE: function () {
89                             if ( node ) {
90                                 node.clear();
91                             }
92                             return {};
93                         },
94                         PUT: function () {
95                             return rData;
96                         },
97                         DEFAULT: function () {
98                             return outputType === 'form' ? sData : rData;
99                         }
100                     };
101
102                     return (methodType[method] || methodType.DEFAULT)();
103                 }
104             };
105
106             return (prepareType[node ? node.type : 'default'] || prepareType.default)();
107         }
108
109         /**
110          * Validating collection import file
111          * @param data
112          * @param checkArray
113          * @returns {*}
114          */
115         function validateFile(data, checkArray){
116             try {
117                 var obj = ParsingJsonService.parseJson(data);
118
119                 return obj && obj.every(function (el){
120                     return checkArray.every(function (arr){
121                         return el.hasOwnProperty(arr);
122                     });
123                 });
124             } catch (e) {
125                 return e;
126             }
127         }
128
129         /**
130          * Return index of selected datastore in list
131          * @param list
132          * @param dataStore
133          * @returns {*}
134          */
135         function getDataStoreIndex(list, dataStore){
136             var rIndex = null,
137                 result = list.some(function (item, index) {
138                     rIndex = index;
139                     return item.label === dataStore;
140                 });
141
142             return result ? rIndex : null;
143         }
144
145         /**
146          * Prepare all necessary data for executing or saving request
147          * @param selectedApi
148          * @param selectedSubApi
149          * @param operation
150          * @param node
151          * @param dataType
152          * @param requestUrl
153          * @param requestData
154          * @param params
155          * @returns {{customRestangular: null, headers: {}, operation: string, reqString: string, reqHeaders: {},
156          *          reqData: {}}}
157          */
158         function prepareAllRequestData(selectedApi, selectedSubApi, operation, node, dataType, requestUrl, requestData,
159                                        params) {
160             var allPreparedData = {
161                 customRestangular: null,
162                 headers: {},
163                 operation: '',
164                 reqString:
165                     selectedSubApi ?
166                         RequestsService.applyParamsToStr(params, selectedSubApi.buildApiRequestString()) :
167                         '',
168                 reqHeaders: {},
169                 reqData: '',
170                 srcData: '',
171             };
172
173             if ( dataType === 'form' && node){
174                 node.buildRequest(RequestBuilderService, requestData, node.module);
175                 allPreparedData.srcData = angular.copy(requestData);
176             }
177             else {
178                 allPreparedData.srcData = requestData;
179             }
180
181             allPreparedData.reqData = RequestsService.applyParamsToObj(params, allPreparedData.srcData);
182
183
184             // prepare req data
185             if (operation === 'GET' || operation === 'DELETE'){
186                 allPreparedData.srcData = null;
187                 allPreparedData.reqData = null;
188             }
189             else if (operation === 'POST'){
190                 allPreparedData.reqData = YangUtilsService.postRequestData(
191                     allPreparedData.reqData,
192                     allPreparedData.reqString,
193                     selectedSubApi
194                 );
195             }
196
197             // set correct host into restangular based on shown data type and prepare data
198             if ( dataType === 'req-data' ){
199                 requestUrl = RequestsService.applyParamsToStr(params, requestUrl);
200                 var parser = locationHelper(requestUrl, ['pathname', 'origin']),
201                     raParam = '';
202
203                 YangUtilsRestangularService.setBaseUrl(parser.origin);
204                 allPreparedData.reqString = parser.pathname.slice(1).split('/');
205                 raParam = allPreparedData.reqString.shift();
206                 allPreparedData.reqString = allPreparedData.reqString.join('/');
207
208                 allPreparedData.customRestangular = YangUtilsRestangularService.one(raParam);
209
210             } else {
211
212                 YangUtilsRestangularService.setBaseUrl(ENV.getBaseURL('MD_SAL'));
213                 allPreparedData.customRestangular  = YangUtilsRestangularService.one('restconf');
214
215                 if ( node ) {
216                     allPreparedData.headers = YangUtilsService.prepareHeaders(allPreparedData.reqData);
217                 }
218             }
219
220             allPreparedData.operation = YangUtilsService.prepareOperation(operation);
221             return allPreparedData;
222         }
223
224         /**
225          * Execute request built from this data
226          * @param selectedApi
227          * @param selectedSubApi
228          * @param operation
229          * @param node
230          * @param dataType
231          * @param requestUrl
232          * @param requestData
233          * @param successCbk
234          * @param errorCbk
235          * @param params
236          */
237         function executeRequestOperation(selectedApi, selectedSubApi, operation, node, dataType, requestUrl,
238                                          requestData, params, successCbk, errorCbk) {
239             var time = {
240                 started: 0,
241                 finished: 0,
242             };
243
244             YangUtilsRestangularService.setFullResponse(true);
245
246             // prepare all necessary data
247             var allPreparedData = prepareAllRequestData(selectedApi, selectedSubApi, operation, node, dataType,
248                 requestUrl, requestData, params);
249
250             // start track time response
251             time.started = new Date().getMilliseconds();
252
253             // executing operation
254             allPreparedData.customRestangular.customOperation(
255                 allPreparedData.operation.toLowerCase(),
256                 allPreparedData.reqString,
257                 null,
258                 allPreparedData.headers,
259                 allPreparedData.reqData
260             )
261             .then(
262                 function (response) {
263                     (successCbk || angular.noop)(finishExecuting(response), response);
264                 },
265                 function (response) {
266                     (errorCbk || angular.noop)(finishExecuting(response), response);
267                 }
268             );
269
270             function finishExecuting(response){
271                 // finish track time response
272                 time.finished = new Date().getMilliseconds();
273                 var spentRequestTime = time.finished - time.started;
274
275                 return {
276                     status: response.status,
277                     statusText: response.statusText,
278                     time: spentRequestTime < 0 ? -(spentRequestTime) : spentRequestTime,
279                     requestData: allPreparedData.reqData,
280                     requestSrcData: allPreparedData.srcData,
281                 };
282             }
283         }
284
285         /**
286          * Method for parsing path to additional properties based on JS LOCATION
287          * @param path
288          * @param properties
289          * @returns {{}}
290          */
291         function locationHelper(path, properties){
292             var parser = document.createElement('a'),
293                 obj = {};
294
295             parser.href = path;
296
297             properties.forEach(function (prop) {
298                 obj[prop] = parser[prop];
299             });
300
301             return obj;
302         }
303
304         /**
305          * Fill node values from response
306          * @param node
307          * @param data
308          */
309         function fillNodeFromResponse(node, data){
310             var props = data ? Object.getOwnPropertyNames(data) : [];
311
312             // fill each property - needed for root mountpoint node,
313             // in other cases there should be only one property anyway
314             props.forEach(function (p) {
315                 node.fill(p, data[p]);
316             });
317         }
318     }
319
320 });