5be603d013403015c53251342deaf7b8181ef6b4
[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         'PathUtilsService',
14         'constants',
15     ];
16
17     function YangmanService(
18         RequestBuilderService,
19         YangUtilsService,
20         YangUtilsRestangularService,
21         ENV,
22         ParsingJsonService,
23         RequestsService,
24         PathUtilsService,
25         constants
26     ){
27         var service = {
28             cutUrl: cutUrl,
29             checkRpcReceivedData: checkRpcReceivedData,
30             executeRequestOperation: executeRequestOperation,
31             fillNodeFromResponse: fillNodeFromResponse,
32             getDataStoreIndex: getDataStoreIndex,
33             handleNodeIdentifier: handleNodeIdentifier,
34             prepareAllRequestData: prepareAllRequestData,
35             prepareReceivedData: prepareReceivedData,
36             putIntoObj: putIntoObj,
37             setSrcDataByDataType: setSrcDataByDataType,
38             validateFile: validateFile,
39         };
40
41         return service;
42
43         /**
44          * Handle param continuum between header path array and node data
45          * @param parametersList
46          * @param selectedSubApi
47          * @param node
48          */
49         function handleNodeIdentifier(parametersList, selectedSubApi, node){
50             var identifier = RequestsService.findIdentifierByParam(
51                 parametersList, selectedSubApi.pathArray[selectedSubApi.pathArray.length - 1]
52             );
53
54             if ( identifier ){
55                 PathUtilsService.fillListNode(node, identifier.label, identifier.value);
56             }
57         }
58
59         /**
60          * Put data to output container if root node is rpc
61          * @param data
62          * @param node
63          * @returns {*}
64          */
65         function checkRpcReceivedData(data, node){
66             return node.type === constants.NODE_RPC ? cutData(data) : data;
67
68             function cutData(data){
69                 return {
70                     output: data[node.label].output,
71                 };
72             }
73         }
74
75         /**
76          * Put source object into destination object by source properties
77          * @param sourceObj
78          * @param destinationObj
79          */
80         function putIntoObj(sourceObj, destinationObj, containter){
81             if ( sourceObj ) {
82                 Object.keys(sourceObj).forEach(function(prop){
83                     destinationObj[containter] = destinationObj[containter] ? destinationObj[containter] : {};
84                     destinationObj[containter][prop] = sourceObj[prop];
85                 });
86             }
87         }
88
89         /**
90          * Prepare request date before filling into node depends on method and node type
91          * @param node
92          * @param method
93          * @param rData
94          * @param sData
95          * @param outputType
96          * @returns {*}
97          */
98         function prepareReceivedData(node, method, rData, sData, outputType){
99             var prepareType = {
100                 rpc: function (){
101
102                     if ( outputType === constants.DISPLAY_TYPE_FORM ){
103                         var dObj = {};
104
105                         if ( !sData ) {
106                             sData = {};
107                             sData[node.label] = {};
108                         }
109
110                         putIntoObj(rData, dObj, node.label);
111                         putIntoObj(sData[node.label] ? sData[node.label] : sData, dObj, node.label);
112                         return dObj;
113                     } else {
114                         return rData;
115                     }
116                 },
117                 default: function (){
118                     var methodType = {
119                         GET: function () {
120                             if ( node ){
121                                 node.clear();
122                             }
123                             return rData;
124                         },
125                         DELETE: function () {
126                             if ( node ) {
127                                 node.clear();
128                             }
129                             return {};
130                         },
131                         DEFAULT: function () {
132                             return rData;
133                         },
134                     };
135
136                     return (methodType[method] || methodType.DEFAULT)();
137                 },
138             };
139
140             return (prepareType[node ? node.type : 'default'] || prepareType.default)();
141         }
142
143         /**
144          * Validating collection import file
145          * @param data
146          * @param checkArray
147          * @returns {*}
148          */
149         function validateFile(data, checkArray){
150             try {
151                 var obj = ParsingJsonService.parseJson(data);
152
153                 return obj && obj.every(function (el){
154                     return checkArray.every(function (arr){
155                         return el.hasOwnProperty(arr);
156                     });
157                 });
158             } catch (e) {
159                 return e;
160             }
161         }
162
163         /**
164          * Return index of selected datastore in list
165          * @param list
166          * @param dataStore
167          * @returns {*}
168          */
169         function getDataStoreIndex(list, dataStore){
170             var rIndex = null,
171                 result = list.some(function (item, index) {
172                     rIndex = index;
173                     return item.label === dataStore;
174                 });
175
176             return result ? rIndex : null;
177         }
178
179         /**
180          * Apply all parametrized values into request (data, url, pathArray)
181          * @param allPreparedData
182          * @param params
183          * @param selSubApiCopy
184          * @param requestUrl
185          */
186         function setParametrizedData(allPreparedData, params, selSubApiCopy, requestUrl){
187             allPreparedData.reqFullUrl = RequestsService.applyParamsToStr(params, requestUrl);
188
189             // apply parametrized value into request data in string form
190             allPreparedData.reqString =
191                 selSubApiCopy ? RequestsService.applyParamsToStr(params, selSubApiCopy.buildApiRequestString()) : '';
192
193             if ( !angular.equals(allPreparedData.reqFullUrl, requestUrl) && selSubApiCopy ){
194                 // fill parametrized data into path array
195                 PathUtilsService.fillPath(selSubApiCopy.pathArray, allPreparedData.reqFullUrl);
196             }
197
198             allPreparedData.reqData = RequestsService.applyParamsToObj(params, allPreparedData.srcData);
199         }
200
201         /**
202          * Set source data into request object based on shown data type
203          * @param allPreparedData
204          * @param node
205          * @param requestData
206          * @param dataType
207          */
208         function setSrcDataByDataType(allPreparedData, node, requestData, dataType){
209             if ( dataType === constants.DISPLAY_TYPE_FORM && node){
210                 node.buildRequest(RequestBuilderService, requestData, node.module);
211                 allPreparedData.srcData = angular.copy(requestData);
212             }
213             else {
214                 allPreparedData.srcData = requestData;
215             }
216         }
217
218         /**
219          * Prepare all necessary data for executing or saving request
220          * @param selectedApi
221          * @param selectedSubApi
222          * @param operation
223          * @param node
224          * @param dataType
225          * @param requestUrl
226          * @param requestData
227          * @param params
228          * @returns {
229          *   {
230          *     customRestangular: null,
231          *     headers: {},
232          *     operation: string,
233          *     reqString: string,
234          *     reqHeaders: {},
235          *     reqData: string,
236          *     srcData: string,
237          *     reqFullUrl:
238          *     string
239          *    }
240          *   }
241          */
242         function prepareAllRequestData(selectedApi, selectedSubApi, operation, node, dataType, requestUrl, requestData,
243                                        params) {
244             var allPreparedData = {
245                     customRestangular: null,
246                     headers: {},
247                     operation: '',
248                     reqString: '',
249                     reqHeaders: {},
250                     reqData: '',
251                     srcData: '',
252                     reqFullUrl: '',
253                 },
254                 selSubApiCopy = angular.copy(selectedSubApi);
255
256             setSrcDataByDataType(allPreparedData, node, requestData, dataType);
257             setParametrizedData(allPreparedData, params, selSubApiCopy, requestUrl);
258
259             // prepare req data
260             if (operation === constants.OPERATION_GET){
261                 allPreparedData.srcData = null;
262                 allPreparedData.reqData = null;
263             }
264             else if ( operation === constants.OPERATION_POST ){
265
266                 if ( selSubApiCopy ) {
267                     allPreparedData.reqData = YangUtilsService.postRequestData(
268                         allPreparedData.reqData,
269                         allPreparedData.reqString,
270                         selSubApiCopy
271                     );
272                 }
273             }
274
275             // set correct host into restangular based on shown data type and prepare data
276             if ( dataType === constants.DISPLAY_TYPE_REQ_DATA ){
277                 var parser = locationHelper(allPreparedData.reqFullUrl, ['pathname', 'origin']),
278                     raParam = '';
279
280                 YangUtilsRestangularService.setBaseUrl(parser.origin);
281                 allPreparedData.reqString = parser.pathname.slice(1).split('/');
282                 raParam = allPreparedData.reqString.shift();
283                 allPreparedData.reqString = allPreparedData.reqString.join('/');
284
285                 allPreparedData.customRestangular = YangUtilsRestangularService.one(raParam);
286
287             } else {
288
289                 YangUtilsRestangularService.setBaseUrl(ENV.getBaseURL('MD_SAL'));
290                 allPreparedData.customRestangular  = YangUtilsRestangularService.one('restconf');
291
292                 if ( node ) {
293                     allPreparedData.headers = YangUtilsService.prepareHeaders(allPreparedData.reqData);
294                 }
295             }
296
297             allPreparedData.operation = YangUtilsService.prepareOperation(operation);
298             return allPreparedData;
299         }
300
301         function cutUrl(url){
302             return url.indexOf('restconf') > -1 ? url.split('restconf')[1].substring(1) : url;
303         }
304
305         /**
306          * Execute request built from this data
307          * @param selectedApi
308          * @param selectedSubApi
309          * @param operation
310          * @param node
311          * @param dataType
312          * @param requestUrl
313          * @param requestData
314          * @param successCbk
315          * @param errorCbk
316          * @param params
317          */
318         function executeRequestOperation(selectedApi, selectedSubApi, operation, node, dataType, requestUrl,
319                                          requestData, params, successCbk, errorCbk) {
320
321             YangUtilsRestangularService.setFullResponse(true);
322
323             var allPreparedData = prepareAllRequestData(
324                 selectedApi, selectedSubApi, operation, node, dataType, requestUrl, requestData, params
325             );
326
327             // executing operation
328             allPreparedData.customRestangular.customOperation(
329                 allPreparedData.operation.toLowerCase(),
330                 allPreparedData.reqString,
331                 null,
332                 allPreparedData.headers,
333                 allPreparedData.reqData
334             )
335             .then(
336                 function (response) {
337                     (successCbk || angular.noop)(finishExecuting(response), response);
338                 },
339                 function (response) {
340                     (errorCbk || angular.noop)(finishExecuting(response), response);
341                 }
342             );
343
344             function finishExecuting(response){
345
346                 return {
347                     status: response.status,
348                     statusText: response.statusText,
349                     time: null,
350                     requestData: allPreparedData.reqData,
351                     requestSrcData: allPreparedData.srcData,
352                 };
353             }
354         }
355
356         /**
357          * Method for parsing path to additional properties based on JS LOCATION
358          * @param path
359          * @param properties
360          * @returns {{}}
361          */
362         function locationHelper(path, properties){
363             var parser = document.createElement('a'),
364                 obj = {};
365
366             parser.href = path;
367
368             properties.forEach(function (prop) {
369                 obj[prop] = parser[prop];
370             });
371
372             return obj;
373         }
374
375         /**
376          * Fill node values from response
377          * @param node
378          * @param data
379          */
380         function fillNodeFromResponse(node, data){
381             var props = data ? Object.getOwnPropertyNames(data) : [];
382
383             // fill each property - needed for root mountpoint node,
384             // in other cases there should be only one property anyway
385             props.forEach(function (p) {
386                 node.fill(p, data[p]);
387             });
388         }
389     }
390
391 });