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