RIFT-15726 - optimize download size -> lodash usage in UI
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / model / DescriptorModelSerializer.js
1
2 /*
3 *
4 * Copyright 2016 RIFT.IO Inc
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19 /**
20 * Created by onvelocity on 10/20/15.
21 */
22
23 import _isNumber from 'lodash/isNumber'
24 import _cloneDeep from 'lodash/cloneDeep'
25 import _isEmpty from 'lodash/isEmpty'
26 import _omit from 'lodash/omit'
27 import _pick from 'lodash/pick'
28 import utils from './../utils'
29 import DescriptorModelFields from './DescriptorModelFields'
30 import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
31
32 let nsdFields = null;
33 let vldFields = null;
34 let vnfdFields = null;
35 let cvnfdFields = null;
36
37
38
39
40 /**
41 * Serialize DescriptorModel JSON into CONFD JSON. Also, cleans up the data as needed.
42 *
43 * @type {{serialize: (function(*=)), ':clean': (function(*=)), nsd: {serialize: (function(*=))}, vld: {serialize: (function(*=))}, vnfd-connection-point-ref: {serialize: (function(*=))}, constituent-vnfd: {serialize: (function(*=))}, vnfd: {serialize: (function(*=))}, vdu: {serialize: (function(*=))}}}
44 */
45 const DescriptorModelSerializer = {
46 serialize(model) {
47 const type = model.uiState && model.uiState.type;
48 const serializer = this[type];
49 if (serializer) {
50 model = serializer.serialize(model);
51 this[':clean'](model);
52 return model;
53 }
54 return false;
55 },
56 ':clean'(model) {
57 // remove uiState from all elements accept nsd and vnfd
58 // remove empty / blank value fields
59 function clean(m) {
60 Object.keys(m).forEach(k => {
61 const isEmptyObject = typeof m[k] === 'object' && _isEmpty(m[k]);
62 if (typeof m[k] === 'undefined' || isEmptyObject || m[k] === '') {
63 delete m[k];
64 }
65 const isMetaAllowed = /^nsd|vnfd$/.test(m.uiState && m.uiState.type);
66 if (k === 'uiState') {
67 if (isMetaAllowed) {
68 // remove any transient ui state properties
69 const uiState = _pick(m.uiState, DescriptorModelFields.meta);
70 if (!_isEmpty(uiState)) {
71 // uiState field must be a string
72 m['meta'] = JSON.stringify(uiState);
73 }
74 }
75 delete m[k];
76 }
77 if (typeof m[k] === 'object') {
78 clean(m[k]);
79 }
80 });
81 }
82 clean(model);
83 return model;
84 },
85 nsd: {
86 serialize(nsdModel) {
87 if(!nsdFields) nsdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd').concat('uiState');
88 const confd = _pick(nsdModel, nsdFields);
89
90 // vnfd is defined in the ETSI etsi_gs reference manual but RIFT does not use it
91 delete confd.vnfd;
92
93 // map the vnfd instances into the CONFD constituent-vnfd ref instances
94 confd['constituent-vnfd'] = confd['constituent-vnfd'].map((d, index) => {
95
96 const constituentVNFD = {
97 'member-vnf-index': d['member-vnf-index'],
98 'vnfd-id-ref': d['vnfd-id-ref']
99 };
100
101 if (d['vnf-configuration']) {
102 const vnfConfig = _cloneDeep(d['vnf-configuration']);
103 const configType = vnfConfig['config-type'] || 'none';
104 // make sure we send the correct values based on config type
105 if (configType === 'none') {
106 constituentVNFD['vnf-configuration'] = {'config-type': 'none'};
107 const configPriority = utils.resolvePath(vnfConfig, 'input-params.config-priority');
108 const configPriorityValue = _isNumber(configPriority) ? configPriority : d.uiState['member-vnf-index'];
109 utils.assignPathValue(constituentVNFD['vnf-configuration'], 'input-params.config-priority', configPriorityValue);
110 } else {
111 // remove any unused configuration options
112 ['netconf', 'rest', 'script', 'juju'].forEach(type => {
113 if (configType !== type) {
114 delete vnfConfig[type];
115 }
116 });
117 constituentVNFD['vnf-configuration'] = vnfConfig;
118 }
119 }
120
121 if (d.hasOwnProperty('start-by-default')) {
122 constituentVNFD['start-by-default'] = d['start-by-default'];
123 }
124
125 return constituentVNFD;
126
127 });
128 for (var key in confd) {
129 checkForChoiceAndRemove(key, confd, nsdModel);
130 }
131 // serialize the VLD instances
132 confd.vld = confd.vld.map(d => {
133 return DescriptorModelSerializer.serialize(d);
134 });
135
136 return cleanEmptyTopKeys(confd);
137
138 }
139 },
140 vld: {
141 serialize(vldModel) {
142 if(!vldFields) vldFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.vld');
143 const confd = _pick(vldModel, vldFields);
144 const property = 'vnfd-connection-point-ref';
145
146 // TODO: There is a bug in RIFT-REST that is not accepting empty
147 // strings for string properties.
148 // once that is fixed, remove this piece of code.
149 // fix-start
150 for (var key in confd) {
151 if (confd.hasOwnProperty(key) && confd[key] === '') {
152 delete confd[key];
153 } else {
154 //removes choice properties from top level object and copies immediate children onto it.
155 checkForChoiceAndRemove(key, confd, vldModel);
156 }
157 }
158
159
160 const deepProperty = 'provider-network';
161 for (var key in confd[deepProperty]) {
162 if (confd[deepProperty].hasOwnProperty(key) && confd[deepProperty][key] === '') {
163 delete confd[deepProperty][key];
164 }
165 }
166 // fix-end
167 confd[property] = confd[property].map(d => DescriptorModelSerializer[property].serialize(d));
168 return cleanEmptyTopKeys(confd);
169 }
170 },
171 'vnfd-connection-point-ref': {
172 serialize(ref) {
173 return _pick(ref, ['member-vnf-index-ref', 'vnfd-id-ref', 'vnfd-connection-point-ref']);
174 }
175 },
176 'internal-connection-point': {
177 serialize(ref) {
178 return _pick(ref, ['id-ref']);
179 }
180 },
181 'constituent-vnfd': {
182 serialize(cvnfdModel) {
183 if(!cvnfdFields) cvnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.constituent-vnfd');
184 return _pick(cvnfdModel, cvnfdFields);
185 }
186 },
187 vnfd: {
188 serialize(vnfdModel) {
189 if(!vnfdFields) vnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('vnfd').concat('uiState');
190 const confd = _pick(vnfdModel, vnfdFields);
191 confd.vdu = confd.vdu.map(d => DescriptorModelSerializer.serialize(d));
192 return cleanEmptyTopKeys(confd);
193 }
194 },
195 vdu: {
196 serialize(vduModel) {
197 const copy = _cloneDeep(vduModel);
198 for (let k in copy) {
199 checkForChoiceAndRemove(k, copy, vduModel)
200 }
201 const confd = _omit(copy, ['uiState']);
202 return cleanEmptyTopKeys(confd);
203 }
204 }
205 };
206
207
208 function checkForChoiceAndRemove(k, confd, model) {
209 let state = model.uiState;
210 if (state.choice) {
211 let choice = state.choice[k]
212 if(choice) {
213 if (choice.constructor.name == "Array") {
214 for(let i = 0; i < choice.length; i++) {
215 for (let key in confd[k][i]) {
216 if(choice[i] && (choice[i].selected.indexOf(key) > -1)) {
217 confd[k][i][key] = confd[k][i][key]
218 }
219 confd[key];
220 };
221 }
222 } else {
223 for (let key in confd[k]) {
224 if(choice && (choice.selected.indexOf(key) > -1)) {
225 confd[key] = confd[k][key]
226 }
227 };
228 delete confd[k];
229 }
230
231 }
232 }
233 return confd;
234 }
235
236 function cleanEmptyTopKeys(m){
237 Object.keys(m).forEach(k => {
238 const isEmptyObject = typeof m[k] === 'object' && _isEmpty(m[k]);
239 if (typeof m[k] === 'undefined' || isEmptyObject || m[k] === '') {
240 delete m[k];
241 }
242 });
243 return m;
244 }
245
246 export default DescriptorModelSerializer;