4 * Copyright 2016 RIFT.IO Inc
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * Created by onvelocity on 10/20/15.
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'
34 let vnfdFields
= null;
35 let cvnfdFields
= null;
41 * Serialize DescriptorModel JSON into CONFD JSON. Also, cleans up the data as needed.
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(*=))}}}
45 const DescriptorModelSerializer
= {
47 const type
= model
.uiState
&& model
.uiState
.type
;
48 const serializer
= this[type
];
50 model
= serializer
.serialize(model
);
51 this[':clean'](model
);
57 // remove uiState from all elements accept nsd and vnfd
58 // remove empty / blank value fields
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
] === '') {
65 const isMetaAllowed
= /^nsd|vnfd$/.test(m
.uiState
&& m
.uiState
.type
);
66 if (k
=== 'uiState') {
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
);
77 if (typeof m
[k
] === 'object') {
87 if(!nsdFields
) nsdFields
= DescriptorModelMetaFactory
.getModelFieldNamesForType('nsd').concat('uiState');
88 const confd
= _pick(nsdModel
, nsdFields
);
90 // vnfd is defined in the ETSI etsi_gs reference manual but RIFT does not use it
93 // map the vnfd instances into the CONFD constituent-vnfd ref instances
94 confd
['constituent-vnfd'] = confd
['constituent-vnfd'].map((d
, index
) => {
96 const constituentVNFD
= {
97 'member-vnf-index': d
['member-vnf-index'],
98 'vnfd-id-ref': d
['vnfd-id-ref']
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
);
111 // remove any unused configuration options
112 ['netconf', 'rest', 'script', 'juju'].forEach(type
=> {
113 if (configType
!== type
) {
114 delete vnfConfig
[type
];
117 constituentVNFD
['vnf-configuration'] = vnfConfig
;
121 if (d
.hasOwnProperty('start-by-default')) {
122 constituentVNFD
['start-by-default'] = d
['start-by-default'];
125 return constituentVNFD
;
128 for (var key
in confd
) {
129 checkForChoiceAndRemove(key
, confd
, nsdModel
);
131 // serialize the VLD instances
132 confd
.vld
= confd
.vld
.map(d
=> {
133 return DescriptorModelSerializer
.serialize(d
);
136 return cleanEmptyTopKeys(confd
);
141 serialize(vldModel
) {
142 if(!vldFields
) vldFields
= DescriptorModelMetaFactory
.getModelFieldNamesForType('nsd.vld');
143 const confd
= _pick(vldModel
, vldFields
);
144 const property
= 'vnfd-connection-point-ref';
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.
150 for (var key
in confd
) {
151 if (confd
.hasOwnProperty(key
) && confd
[key
] === '') {
154 //removes choice properties from top level object and copies immediate children onto it.
155 checkForChoiceAndRemove(key
, confd
, vldModel
);
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
];
167 confd
[property
] = confd
[property
].map(d
=> DescriptorModelSerializer
[property
].serialize(d
));
168 return cleanEmptyTopKeys(confd
);
171 'vnfd-connection-point-ref': {
173 return _pick(ref
, ['member-vnf-index-ref', 'vnfd-id-ref', 'vnfd-connection-point-ref']);
176 'internal-connection-point': {
178 return _pick(ref
, ['id-ref']);
181 'constituent-vnfd': {
182 serialize(cvnfdModel
) {
183 if(!cvnfdFields
) cvnfdFields
= DescriptorModelMetaFactory
.getModelFieldNamesForType('nsd.constituent-vnfd');
184 return _pick(cvnfdModel
, cvnfdFields
);
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
);
196 serialize(vduModel
) {
197 const copy
= _cloneDeep(vduModel
);
198 for (let k
in copy
) {
199 checkForChoiceAndRemove(k
, copy
, vduModel
)
201 const confd
= _omit(copy
, ['uiState']);
202 return cleanEmptyTopKeys(confd
);
208 function checkForChoiceAndRemove(k
, confd
, model
) {
209 let state
= model
.uiState
;
211 let choice
= state
.choice
[k
]
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
]
223 for (let key
in confd
[k
]) {
224 if(choice
&& (choice
.selected
.indexOf(key
) > -1)) {
225 confd
[key
] = confd
[k
][key
]
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
] === '') {
246 export default DescriptorModelSerializer
;