RIFT-15726 - optimize download size -> lodash usage in UI
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / model / DescriptorModelFactory.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 /**
19 * Created by onvelocity on 11/23/15.
20 */
21
22 'use strict';
23
24 import _isEmpty from 'lodash/isEmpty'
25 import _cloneDeep from 'lodash/cloneDeep'
26 import d3 from 'd3'
27 import UID from './../UniqueId'
28 import guid from '../guid'
29 import Position from './../graph/Position'
30 import ColorGroups from '../ColorGroups'
31 import DescriptorModel from './DescriptorModel'
32 import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
33 import DescriptorModelMetaProperty from './DescriptorModelMetaProperty'
34
35 import Classifier from './descriptors/Classifier'
36 import ClassifierMatchAttributes from './descriptors/ClassifierMatchAttributes'
37 import ConnectionPoint from './descriptors/ConnectionPoint'
38 import VnfdConnectionPointRef from './descriptors/VnfdConnectionPointRef'
39 import ConstituentVnfd from './descriptors/ConstituentVnfd'
40 import ConstituentVnfdConnectionPoint from './descriptors/ConstituentVnfdConnectionPoint'
41 import ForwardingGraph from './descriptors/ForwardingGraph'
42 import InternalConnectionPoint from './descriptors/InternalConnectionPoint'
43 import InternalVirtualLink from './descriptors/InternalVirtualLink'
44 import NetworkService from './descriptors/NetworkService'
45 import PhysicalNetworkFunction from './descriptors/PhysicalNetworkFunction'
46 import RecordServicePath from './descriptors/RecordServicePath'
47 import RspConnectionPointRef from './descriptors/RspConnectionPointRef'
48 import VirtualDeploymentUnit from './descriptors/VirtualDeploymentUnit'
49 import VirtualLink from './descriptors/VirtualLink'
50 import VirtualNetworkFunction from './descriptors/VirtualNetworkFunction'
51 import VirtualNetworkFunctionReadOnlyWrapper from './descriptors/VirtualNetworkFunctionReadOnlyWrapper'
52 import InternalConnectionPointRef from './descriptors/InternalConnectionPointRef'
53 import VirtualNetworkFunctionConnectionPoint from './descriptors/VirtualNetworkFunctionConnectionPoint'
54 import VirtualDeploymentUnitInternalConnectionPoint from './descriptors/VirtualDeploymentUnitInternalConnectionPoint'
55
56 function findChildDescriptorModelAndUpdateModel(model, parent) {
57 if (parent instanceof DescriptorModel) {
58 const child = parent.findChildByUid(model);
59 if (child) {
60 child.model = model;
61 return child;
62 }
63 }
64 }
65
66 let identity = 0;
67
68 class DescriptorModelFactory {
69
70
71 static containerIdentity(d) {
72 const parentId = UID.from(d && d.parent);
73 // note the incremental counter is to always force d3 models to update
74 return (parentId ? parentId + ':' : '') + UID.from(d) + ':' + identity++;
75 }
76
77 /**
78 * Create a reduce function that creates a DescriptorModel element tree
79 * representation of a Catalog Item and then returns a flat list of
80 * DescriptorModel elements. The first item in the array is root.
81
82 * @returns {Function}
83 */
84 static buildCatalogItemFactory(catalogs) {
85
86 function findCatalogItemByTypeAndId(type, id) {
87 return catalogs.filter(catalog => catalog.type === type).reduce((a, b) => a.concat(b.descriptors), []).filter(d => d.id === id)[0];
88 }
89
90 function mapVLD(vld, containerList) {
91 containerList.push(vld);
92 vld.connection.forEach(d => containerList.push(d));
93 }
94
95 function mapIVLD(ivld, containerList) {
96 containerList.push(ivld);
97 ivld.connection.forEach(d => containerList.push(d));
98 }
99
100 function mapRspConnectionPoint(cp, containerList) {
101 containerList.push(cp);
102 }
103
104 function mapClassifier(classifier, containerList) {
105 containerList.push(classifier);
106 // get the referenced vnfd required for rendering the connection point
107 const vnfdRef = findCatalogItemByTypeAndId('vnfd', classifier.model['vnfd-id-ref']);
108 if (vnfdRef) {
109 classifier.uiState.vnfdRef = vnfdRef;
110 }
111 classifier.matchAttributes.forEach(attr => containerList.push(attr));
112 }
113
114 function mapRSP(rsp, containerList) {
115 containerList.push(rsp);
116 rsp.vnfdConnectionPointRef.forEach(cpRef => mapRspConnectionPoint(cpRef, containerList));
117 }
118
119 function mapFG(fg, containerList) {
120 containerList.push(fg);
121 fg.rsp.forEach(rsp => mapRSP(rsp, containerList));
122 fg.classifier.forEach(classifier => mapClassifier(classifier, containerList));
123 }
124
125 function mapVDU(vdu, containerList) {
126 containerList.push(vdu);
127 vdu.connectionPoint.forEach(d => containerList.push(d));
128 }
129
130 function mapCVNFD(cvnfd, containerList) {
131 // get the referenced vnfd required for rendering the connection points
132 const vnfdRef = findCatalogItemByTypeAndId('vnfd', cvnfd.model['vnfd-id-ref']);
133 if (!vnfdRef) {
134 console.warn('No VNFD found in catalog with id: ' + cvnfd['vnfd-id-ref']);
135 }
136 cvnfd.vnfdRef = vnfdRef;
137 containerList.push(cvnfd);
138 cvnfd.vld.forEach(vld => mapIVLD(vld, containerList));
139 cvnfd.connectionPoint.forEach(cp => containerList.push(cp));
140 }
141
142 function mapNSD(nsd, containerList) {
143 containerList.push(nsd);
144 nsd.constituentVnfd.forEach(cvnfd => mapCVNFD(cvnfd, containerList));
145 nsd.vld.forEach(vld => mapVLD(vld, containerList));
146 nsd.vnffgd.forEach(fg => mapFG(fg, containerList));
147 }
148
149 function mapVNFD(vnfd, containerList) {
150 containerList.push(vnfd);
151 vnfd.vdu.forEach(vdu => mapVDU(vdu, containerList));
152 vnfd.vld.forEach(vld => mapIVLD(vld, containerList));
153 vnfd.connectionPoint.forEach(cp => containerList.push(cp));
154 }
155
156 function mapPNFD(pnfd, containerList) {
157 containerList.push(pnfd);
158 }
159
160 return (containerList, obj) => {
161 if (_isEmpty(obj)) {
162 return containerList;
163 }
164 switch (obj.uiState.type) {
165 case 'nsd':
166 mapNSD(DescriptorModelFactory.newNetworkService(obj), containerList);
167 break;
168 case 'vnfd':
169 mapVNFD(DescriptorModelFactory.newVirtualNetworkFunction(obj), containerList);
170 break;
171 case 'pnfd':
172 mapPNFD(DescriptorModelFactory.newPhysicalNetworkFunction(obj), containerList);
173 break;
174 default:
175 throw new ReferenceError('only catalog items can be rendered in the canvas. unexpected type: ' + obj.uiState.type);
176 }
177 return containerList;
178 };
179
180 }
181
182 static newNetworkService(model, parent) {
183 return findChildDescriptorModelAndUpdateModel(model, parent) || new NetworkService(model, parent);
184 }
185
186 static newConstituentVnfd(model, parent) {
187 return findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfd(model, parent);
188 }
189
190 static newVirtualNetworkFunction(model, parent) {
191 return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunction(model, parent);
192 }
193
194 static newVirtualNetworkFunctionConnectionPoint(model, parent) {
195 return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunctionConnectionPoint(model, parent);
196 }
197
198 static newInternalConnectionPoint(model, parent) {
199 return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalConnectionPoint(model, parent);
200 }
201
202 static newVirtualDeploymentUnit(model, parent) {
203 return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnit(model, parent);
204 }
205
206 static newVirtualDeploymentUnitInternalConnectionPoint(model, parent) {
207 return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnitInternalConnectionPoint(model, parent);
208 }
209
210 static newVirtualLink(model, parent) {
211 return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualLink(model, parent);
212 }
213
214 static newInternalVirtualLink(model, parent) {
215 return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalVirtualLink(model, parent);
216 }
217
218 static newPhysicalNetworkFunction(model, parent) {
219 return findChildDescriptorModelAndUpdateModel(model, parent) || new PhysicalNetworkFunction(model, parent);
220 }
221
222 static newConstituentVnfdConnectionPoint(model, parent) {
223 return findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfdConnectionPoint(model, parent);
224 }
225
226 static newVnfdConnectionPointRef(model, parent) {
227 return findChildDescriptorModelAndUpdateModel(model, parent) || new VnfdConnectionPointRef(model, parent);
228 }
229
230 static newForwardingGraph(model, parent) {
231 return findChildDescriptorModelAndUpdateModel(model, parent) || new ForwardingGraph(model, parent);
232 }
233
234 static newRecordServicePath(model, parent) {
235 return findChildDescriptorModelAndUpdateModel(model, parent) || new RecordServicePath(model, parent);
236 }
237
238 static newRspConnectionPointRef(model, parent) {
239 return findChildDescriptorModelAndUpdateModel(model, parent) || new RspConnectionPointRef(model, parent);
240 }
241
242 static newVirtualNetworkFunctionReadOnlyWrapper(vnfdToWrap, parent) {
243 let model;
244 if (vnfdToWrap instanceof DescriptorModel) {
245 if (vnfdToWrap instanceof VirtualNetworkFunction) {
246 model = vnfdToWrap.model;
247 } else {
248 throw new ReferenceError(`expected a VirtualNetworkFunction but got a ${vnfdToWrap.className}`);
249 }
250 } else {
251 model = vnfdToWrap;
252 }
253 return new VirtualNetworkFunctionReadOnlyWrapper(_cloneDeep(model), parent);
254 }
255
256 static newClassifier(model, parent) {
257 return findChildDescriptorModelAndUpdateModel(model, parent) || new Classifier(model, parent);
258 }
259
260 static newClassifierMatchAttributes(model, parent) {
261 return findChildDescriptorModelAndUpdateModel(model, parent) || new ClassifierMatchAttributes(model, parent);
262 }
263
264 static newInternalConnectionPointRef(model, parent) {
265 // note do not find children bc model is not an object it is a leaf-list primative and so the class manages it
266 return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalConnectionPointRef(model, parent);
267 }
268
269 /**
270 * Special instance of a RecordServicePath that will create its parent ForwardingGraph it does not exist.
271 *
272 * This is useful to present a stub RSP as an initiator to create Paths without explicitly creating an RSP - just
273 * start building a path and it auto-magically builds the RSP.
274 *
275 * @param parent
276 * @param model
277 */
278 static newRecordServicePathFactory(model, parent) {
279 return new AutoCreateRecordServicePath(model, parent);
280 }
281
282 static isContainer(obj) {
283 return obj instanceof DescriptorModel;
284 }
285
286 static isConnector(obj) {
287 return obj instanceof ConnectionPoint;
288 }
289
290 static isConnectionPoint(obj) {
291 return obj instanceof ConnectionPoint;
292 }
293
294 static isConstituentVnfd(obj) {
295 return obj instanceof ConstituentVnfd;
296 }
297
298 static isConstituentVnfdWithServiceChain(obj, chain) {
299 return obj instanceof ConstituentVnfd && obj.vnfdServiceFunctionChain === chain;
300 }
301
302 static isNetworkService(obj) {
303 return obj instanceof NetworkService;
304 }
305
306 static isVnfdConnectionPointRef(obj) {
307 return obj instanceof VnfdConnectionPointRef;
308 }
309
310 static isRecordServicePath(obj) {
311 return obj instanceof RecordServicePath;
312 }
313
314 static isRspConnectionPointRef(obj) {
315 return obj instanceof RspConnectionPointRef;
316 }
317
318 static isVirtualLink(obj) {
319 return obj instanceof VirtualLink;
320 }
321
322 static isVirtualNetworkFunction(obj) {
323 return obj instanceof VirtualNetworkFunction;
324 }
325
326 static isForwardingGraph(obj) {
327 return obj instanceof ForwardingGraph;
328 }
329
330 static isInternalConnectionPoint(obj) {
331 return obj instanceof InternalConnectionPoint;
332 }
333
334 static isInternalVirtualLink(obj) {
335 return obj instanceof InternalVirtualLink;
336 }
337
338 static get VirtualLink () {
339 return VirtualLink;
340 }
341
342 static get NetworkService () {
343 return NetworkService;
344 }
345
346 static get ForwardingGraph () {
347 return ForwardingGraph;
348 }
349
350 static get VirtualNetworkFunction () {
351 return VirtualNetworkFunction;
352 }
353
354 static get ConstituentVnfd () {
355 return ConstituentVnfd;
356 }
357
358 static get Classifier() {
359 return Classifier;
360 }
361
362 static get ClassifierMatchAttributes() {
363 return ClassifierMatchAttributes;
364 }
365
366 static get VnfdConnectionPointRef() {
367 return VnfdConnectionPointRef;
368 }
369
370 static get VirtualDeploymentUnit() {
371 return VirtualDeploymentUnit;
372 }
373
374 static get InternalConnectionPoint() {
375 return InternalConnectionPoint;
376 }
377
378 static get InternalVirtualLink() {
379 return InternalVirtualLink;
380 }
381
382 static get InternalConnectionPointRef() {
383 return InternalConnectionPointRef;
384 }
385
386 static get VirtualNetworkFunctionConnectionPoint() {
387 return VirtualNetworkFunctionConnectionPoint;
388 }
389
390 static get VirtualDeploymentUnitInternalConnectionPoint() {
391 return VirtualDeploymentUnitInternalConnectionPoint;
392 }
393
394 }
395
396 /**
397 * Auto create a RecordServicePath when a VnfdConnectionPointRef is added.
398 */
399 class AutoCreateRecordServicePath extends RecordServicePath {
400
401 constructor(model, parent) {
402 super(model, null);
403 this.parent = parent;
404 this.isFactory = true;
405 }
406
407 create() {
408 return this.parent.createRsp();
409 }
410
411 createVnfdConnectionPointRef(obj) {
412 const rsp = this.create();
413 rsp.createVnfdConnectionPointRef(obj);
414 return rsp;
415 }
416
417 }
418
419 export default DescriptorModelFactory;