Add new code new version
[sdc.git] / openecomp-ui / src / nfvo-utils / RestAPIUtil.js
diff --git a/openecomp-ui/src/nfvo-utils/RestAPIUtil.js b/openecomp-ui/src/nfvo-utils/RestAPIUtil.js
new file mode 100644 (file)
index 0000000..2473473
--- /dev/null
@@ -0,0 +1,288 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T 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=========================================================
+ */
+
+import _extend from 'lodash/extend.js';
+import _clone from 'lodash/clone.js';
+import _defaults from 'lodash/defaults.js';
+import $ from 'jquery';
+import uuid from 'uuid-js';
+import md5 from 'md5';
+
+import store from 'sdc-app/AppStore.js';
+import {actionTypes as LoaderConstants} from 'nfvo-components/loader/LoaderConstants.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import errorResponseHandler from './ErrorResponseHandler.js';
+
+const methodMap = {
+       'create': 'POST',
+       'update': 'PUT',
+       'delete': 'DELETE',
+       'read': 'GET'
+};
+const AUTHORIZATION_HEADER = 'X-AUTH-TOKEN';
+const STORAGE_AUTH_KEY = 'sdc-auth-token';
+const REQUEST_ID_HEADER = 'X-ECOMP-RequestID';
+const CONTENT_MD5_HEADER = 'Content-MD5';
+const namedParam = /{(\w+)}/g;
+const queryParamsNames = {
+       pageStart: 'pageStart',
+       pageSize: 'pageSize',
+       sortField: 'sortField',
+       sortDir: 'sortDir',
+       filtering: 'filter'
+};
+
+
+// jQuery binary transport to download files through XHR
+// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
+// https://github.com/henrya/js-jquery/tree/master/BinaryTransport
+$.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) {
+       // check for conditions and support for blob / arraybuffer response type
+       if (window.FormData && ((options.dataType && (options.dataType === 'binary')) ||
+               (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) ||
+               (window.Blob && options.data instanceof Blob))))
+       ) {
+               return {
+                       // create new XMLHttpRequest
+                       send: function (headers, callback) {
+                               // setup all variables
+                               var xhr = new XMLHttpRequest(),
+                                       url = options.url,
+                                       type = options.type,
+                                       async = options.async || true,
+                               // blob or arraybuffer. Default is blob
+                                       dataType = options.responseType || 'blob',
+                                       data = options.data || null,
+                                       username = options.username || null,
+                                       password = options.password || null;
+
+                               xhr.addEventListener('load', function () {
+                                       var data = {};
+                                       data[options.dataType] = xhr.response;
+                                       // make callback and send data
+                                       callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
+                               });
+
+                               xhr.open(type, url, async, username, password);
+
+                               // setup custom headers
+                               for (var i in headers) {
+                                       xhr.setRequestHeader(i, headers[i]);
+                               }
+
+                               xhr.responseType = dataType;
+                               xhr.send(data);
+                       },
+                       abort: function () {
+                       }
+               };
+       }
+});
+
+$(document).ajaxStart(()=> store.dispatch({type: LoaderConstants.SHOW}));
+$(document).ajaxStop(()=> store.dispatch({type: LoaderConstants.HIDE}));
+
+function urlError() {
+       throw new Error('A "url" property or function must be specified');
+};
+
+export function makeQueryParams(options) {
+       var qParams = {};
+       if (options.pagination) {
+               qParams[queryParamsNames.pageStart] = options.pagination.pageStart;
+               qParams[queryParamsNames.pageSize] = options.pagination.pageSize;
+       }
+       if (options.sorting) {
+               qParams[queryParamsNames.sortField] = options.sorting.sortField;
+               qParams[queryParamsNames.sortDir] = options.sorting.sortDir;
+       }
+       if (options.filtering) {
+               qParams[queryParamsNames.filtering] = JSON.stringify(options.filtering);
+       }
+
+       return _defaults(qParams, options.qParams);
+}
+
+function appendQueryParam(p, value) {
+       var str = '';
+
+       if (value instanceof Array) {
+               if (value.length === 1) {
+                       str = appendQueryParam(p, value[0]);
+               } else if (value.length > 1) {
+                       str = appendQueryParam(p, value.shift()) + '&' + appendQueryParam(p, value);
+               }
+       } else {
+               str = p + '=' + encodeURIComponent(value);
+       }
+
+       return str;
+}
+
+function appendQueryString(url, qParams) {
+       var str = '';
+       for (var param in qParams) {
+               str += (str ? '&' : '') + appendQueryParam(param, qParams[param]);
+       }
+       return url + (str ? '?' : '') + str;
+}
+
+function composeURL(baseUrl, options) {
+       var url = baseUrl || urlError();
+       if (options.url) {
+               delete options.url;
+       }
+
+       var qParams = makeQueryParams(options);
+       url = appendQueryString(url, qParams);
+
+       var matches = url.match(namedParam);
+       if (matches) {
+               for (var i = 0; i < matches.length; i++) {
+                       var param = matches[i].substring(1, matches[i].length - 1);
+                       var value = (options.params && options.params[param]);
+
+                       if (value === undefined) {
+                               value = options[param];
+                       }
+                       url = url.replace(matches[i], encodeURIComponent(value));
+               }
+       }
+
+       return url;
+}
+
+function applyMD5Header(options, data) {
+       if (options.md5) {
+               let headers = options.headers;
+               headers[CONTENT_MD5_HEADER] = window.btoa(md5(JSON.stringify(data)).toLowerCase());
+       }
+}
+
+function applySecurity(options, data) {
+       var headers = options.headers || (options.headers = {});
+
+       var authToken = localStorage.getItem(STORAGE_AUTH_KEY);
+       if (authToken) {
+               headers[AUTHORIZATION_HEADER] = authToken;
+       }
+
+       var attApiHeaders = Configuration.get('ATTApiHeaders'),
+               attUidHeader = attApiHeaders && attApiHeaders.userId;
+       if (attUidHeader) {
+               headers[attUidHeader.name] = attUidHeader.value;
+       }
+
+       headers[REQUEST_ID_HEADER] = uuid.create().toString();
+
+       applyMD5Header(options, data);
+}
+
+function handleResponse(options) {
+       var authToken = options.xhr.getResponseHeader(AUTHORIZATION_HEADER);
+       var prevToken = options.headers && options.headers[AUTHORIZATION_HEADER];
+       if (authToken && authToken !== prevToken) {
+               if (authToken === 'null') {
+                       localStorage.removeItem(STORAGE_AUTH_KEY);
+               } else {
+                       localStorage.setItem(STORAGE_AUTH_KEY, authToken);
+               }
+       }
+}
+
+function sync(baseUrl, method, options, data) {
+
+       options = options ? _clone(options) : {};
+
+       var type = methodMap[method];
+       _defaults(options || (options = {}));
+       var params = {
+               type: type,
+               dataType: 'json'
+       };
+       params.url = composeURL(baseUrl, options);
+
+       if ((method === 'create' || method === 'update') && data instanceof FormData) {
+               params.contentType = 'multipart/form-data';
+               params.data = data;
+       }
+       else if (method === 'create' || method === 'update') {
+               params.contentType = 'application/json';
+               params.data = JSON.stringify(data);
+       }
+
+       if (params.type !== 'GET') {
+               params.processData = false;
+       }
+       var success = options.success;
+       options.success = function (resp) {
+               if (success) {
+                       handleResponse(options);
+                       success.call(options.context, _clone(resp), resp, options);
+               }
+       };
+
+       options.error = options.error || errorResponseHandler;
+
+       if (typeof options.progressCallback === 'function' && options.fileSize) {
+               const {fileSize} = options;
+               options.xhrFields = {
+                       // add listener to XMLHTTPRequest object directly for progress (jquery doesn't have this yet)
+                       onprogress: function (progress) {
+                               // calculate upload progress
+                               let percentage = Math.floor((progress.loaded / fileSize) * 100);
+                               // log upload progress to console
+                               //console.log('progress', percentage);
+                               options.progressCallback(percentage);
+                               if (percentage === 100) {
+                                       console.log('DONE!');
+                               }
+                       }
+               };
+       }
+
+       applySecurity(options, data);
+
+       if (DEBUG) {
+               console.log('--> Making REST call (' + type + '): ' + params.url);
+       }
+       var xhr = options.xhr = $.ajax(_extend(params, options));
+       return xhr;
+}
+
+export default {
+
+       fetch(baseUrl, options) {
+               return sync(baseUrl, 'read', options);
+       },
+
+       save(baseUrl, data, options) {
+               return sync(baseUrl, 'update', options, data);
+       },
+
+       create(baseUrl, data, options) {
+               return sync(baseUrl, 'create', options, data);
+       },
+
+       destroy(baseUrl, options) {
+               return sync(baseUrl, 'delete', options);
+       }
+
+};