update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / framework / core / modules / api / modelAPI.js
1 /*
2 *
3 * Copyright 2016 RIFT.IO Inc
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18 // DescriptorModelMeta API (NSD + VNFD)
19
20
21 var Schema = {};
22 var rp = require('request-promise');
23 var Promise = require('promise');
24 var constants = require('../../api_utils/constants');
25 var utils = require('../../api_utils/utils');
26 var _ = require('lodash');
27 var cors = require('cors');
28 var bodyParser = require('body-parser');
29 var utils = require('../../api_utils/utils');
30 var configuration = require('./configuration');
31
32 var router = require('express').Router();
33
34
35 router.use(bodyParser.json());
36 router.use(cors());
37 router.use(bodyParser.urlencoded({
38 extended: true
39 }));
40
41 router.get('/model', cors(), function (req, res) {
42 get(req).then(function (response) {
43 utils.sendSuccessResponse(response, res);
44 }, function (error) {
45 utils.sendErrorResponse(error, res);
46 });
47 });
48
49 router.patch('/model', cors(), function (req, res) {
50 update(req).then(function (response) {
51 utils.sendSuccessResponse(response, res);
52 }, function (error) {
53 utils.sendErrorResponse(error, res);
54 });
55 });
56
57 router.put('/model', cors(), function (req, res) {
58 add(req).then(function (response) {
59 utils.sendSuccessResponse(response, res);
60 }, function (error) {
61 utils.sendErrorResponse(error, res);
62 });
63 });
64
65 router.delete('/model', cors(), function (req, res) {
66 remove(req).then(function (response) {
67 utils.sendSuccessResponse(response, res);
68 }, function (error) {
69 utils.sendErrorResponse(error, res);
70 });
71 });
72
73 module.exports = {
74 getRouter: function () {
75 return router;
76 },
77 init: function () {}
78 };
79
80 get = function (req) {
81 var backend = configuration.getBackendAPI();
82 var modelPath = req.query['path'];
83 var requestHeaders = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
84 'Authorization': req.session && req.session.authorization
85 })
86 return new Promise(function (resolve, reject) {
87 Promise.all([
88 rp({
89 uri: backend + '/config' + modelPath,
90 method: 'GET',
91 headers: requestHeaders,
92 forever: constants.FOREVER_ON,
93 rejectUnauthorized: false,
94 resolveWithFullResponse: true
95 // }),
96 // rp({
97 // uri: utils.projectContextUrl(req, backend + '/api/operational' + modelPath),
98 // method: 'GET',
99 // headers: requestHeaders,
100 // forever: constants.FOREVER_ON,
101 // rejectUnauthorized: false,
102 // resolveWithFullResponse: true
103 })
104 ]).then(function (results) {
105 var response = {
106 statusCode: results[0].statusCode || 200,
107 data: [null]
108 }
109 if (results[0].body && !results[0].error) {
110 var result = JSON.parse(results[0].body);
111 if (result.collection) {
112 result = result.collection[Object.keys(result.collection)[0]];
113 if (!result.length) {
114 result = null;
115 } else if (result.length === 1) {
116 result = result[0];
117 }
118 }
119 response.data = result;
120 }
121 resolve(response);
122
123 }).catch(function (error) {
124 var res = {};
125 console.log('Problem with model get', error);
126 res.statusCode = error.statusCode || 500;
127 res.errorMessage = {
128 error: 'Failed to get model: ' + error
129 };
130 reject(res);
131 });
132 });
133 };
134
135 add = function (req) {
136 var backend = configuration.getBackendAPI();
137 var modelPath = req.query['path'];
138 var targetProperty = modelPath.split('/').pop();
139 var newElement = {};
140 var data = {};
141 console.log(req.body);
142 _.forIn(req.body, function (value, key) {
143 if (_.isObject(value)) {
144 if (value.type === 'leaf_empty') {
145 if (value.data) {
146 data[key] = ' ';
147 }
148 } else if (value.type === 'leaf_list') {
149 data[key] = value.data.add;
150 }
151 } else {
152 data[key] = value;
153 }
154 });
155 newElement[targetProperty] = [data];
156 console.log(newElement);
157 var target = backend + '/config' + modelPath;
158 var method = 'POST'
159 var requestHeaders = _.extend({},
160 constants.HTTP_HEADERS.accept.data, {
161 'Authorization': req.session && req.session.authorization
162 });
163 return new Promise(function (resolve, reject) {
164 rp({
165 uri: target,
166 method: method,
167 headers: requestHeaders,
168 forever: constants.FOREVER_ON,
169 json: newElement,
170 rejectUnauthorized: false,
171 resolveWithFullResponse: true
172 }).then(function (results) {
173 var response = {};
174 response.data = {
175 path: modelPath,
176 data: data
177 };
178 response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK;
179 console.log(response);
180 resolve(response);
181 }).catch(function (result) {
182 var response = {};
183 var error = {};
184 if (result.error['rpc-reply']) {
185 error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
186 error.message = result.error['rpc-reply']['rpc-error']['error-message'];
187 error.rpcError = result.error['rpc-reply']['rpc-error']
188 } else {
189 error.type = 'api-error';
190 error.message = 'invalid api call';
191 }
192 console.log('Problem with model update', error);
193 response.statusCode = error.statusCode || 500;
194 response.error = error;
195 reject(response);
196 });
197 });
198 };
199
200 update = function (req) {
201 var backend = configuration.getBackendAPI();
202 var modelPath = req.query['path'];
203 var requestHeaders = _.extend({},
204 constants.HTTP_HEADERS.accept.data, {
205 'Authorization': req.session && req.session.authorization
206 });
207 var base = backend + '/config' + modelPath + '/';
208
209 function getUpdatePromise(name, value) {
210 var data = {};
211 data[name] = value;
212 return new Promise(function (resolve, reject) {
213 rp({
214 uri: base + name,
215 method: value ? 'PATCH' : 'DELETE',
216 headers: requestHeaders,
217 forever: constants.FOREVER_ON,
218 json: data,
219 rejectUnauthorized: false,
220 resolveWithFullResponse: true
221 }).then(function (result) {
222 resolve({
223 element: name,
224 success: true,
225 value: value
226 });
227 }).catch(function (result) {
228 var error = {};
229 if (result.error['rpc-reply']) {
230 error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
231 error.message = result.error['rpc-reply']['rpc-error']['error-message'];
232 error.rpcError = result.error['rpc-reply']['rpc-error']
233 } else {
234 error.type = 'api-error';
235 error.message = 'invalid api call';
236 }
237 resolve({
238 element: name,
239 success: false,
240 error: error,
241 value: value
242 });
243 })
244 })
245 }
246
247 function getDeletePromise(targetProp, item) {
248 if (item) {
249 targetProp = targetProp + '/' + item;
250 }
251 return getUpdatePromise(targetProp, '');
252 }
253
254 var updates = [];
255 _.forIn(req.body, function (value, key) {
256 var data = {};
257 if (_.isObject(value)) {
258 if (value.type === 'leaf_list') {
259 _.forEach(value.data.remove, function (v) {
260 updates.push(getDeletePromise(key))
261 })
262 _.forEach(value.data.add, function (v) {
263 updates.push(getUpdatePromise(key, v))
264 })
265 } else if (value.type === 'leaf_empty') {
266 if (value.data) {
267 updates.push(getUpdatePromise(key, ' '))
268 } else {
269 updates.push(getDeletePromise(key))
270 }
271 }
272 } else {
273 updates.push(getUpdatePromise(key, value))
274 }
275 })
276
277 return new Promise(function (resolve, reject) {
278 Promise.all(updates).then(function (results) {
279 var response = {};
280 var output = {};
281 var hasError = false;
282 _.forEach(results, function (result) {
283 var record = {};
284 if (output[result.element]) {
285 if (_.isArray(output[result.element].value)) {
286 output[result.element].value.push(result.value);
287 } else {
288 output[result.element].value = [output[result.element].value, result.value];
289 }
290 } else {
291 output[result.element] = result;
292 }
293 hasError = hasError || !result.success
294 })
295 response.data = {
296 result: output,
297 hasError: hasError
298 };
299 response.statusCode = constants.HTTP_RESPONSE_CODES.SUCCESS.OK;
300 console.log(response);
301 resolve(response);
302 }).catch(function (result) {
303 var response = {};
304 var error = {};
305 if (result.error['rpc-reply']) {
306 error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
307 error.message = result.error['rpc-reply']['rpc-error']['error-message'];
308 error.rpcError = result.error['rpc-reply']['rpc-error']
309 } else {
310 error.type = 'api-error';
311 error.message = 'invalid api call';
312 }
313 console.log('Problem with model update', error);
314 response.statusCode = error.statusCode || 500;
315 response.error = error;
316 reject(response);
317 });
318 });
319 };
320
321 remove = function (req) {
322 var backend = configuration.getBackendAPI();
323 var modelPath = req.query['path'];
324 var target = backend + '/config' + modelPath;
325 var requestHeaders = _.extend({},
326 constants.HTTP_HEADERS.accept.data,
327 constants.HTTP_HEADERS.content_type.data, {
328 'Authorization': req.session && req.session.authorization
329 })
330 return new Promise(function (resolve, reject) {
331 rp({
332 url: target,
333 method: 'DELETE',
334 headers: requestHeaders,
335 forever: constants.FOREVER_ON,
336 rejectUnauthorized: false,
337 }).then(function (response) {
338 return resolve({
339 statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK,
340 data: modelPath
341 });
342 }).catch(function (result) {
343 var response = {};
344 var error = {};
345 if (result.error['rpc-reply']) {
346 error.type = result.error['rpc-reply']['rpc-error']['error-tag'];
347 error.message = result.error['rpc-reply']['rpc-error']['error-message'];
348 error.rpcError = result.error['rpc-reply']['rpc-error']
349 } else {
350 error.type = 'api-error';
351 error.message = 'invalid api call';
352 }
353 console.log('Problem with model update', error);
354 response.statusCode = error.statusCode || 500;
355 response.error = error;
356 reject(response);
357 });
358 })
359 }