Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / model / DescriptorModelFactory.js
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFactory.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFactory.js
new file mode 100644 (file)
index 0000000..68b70d7
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   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.
+ *
+ */
+/**
+ * Created by onvelocity on 11/23/15.
+ */
+
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+import UID from './../UniqueId'
+import guid from '../guid'
+import Position from './../graph/Position'
+import ColorGroups from '../ColorGroups'
+import DescriptorModel from './DescriptorModel'
+import DescriptorModelMetaFactory from './DescriptorModelMetaFactory'
+import DescriptorModelMetaProperty from './DescriptorModelMetaProperty'
+
+import Classifier from './descriptors/Classifier'
+import ClassifierMatchAttributes from './descriptors/ClassifierMatchAttributes'
+import ConnectionPoint from './descriptors/ConnectionPoint'
+import VnfdConnectionPointRef from './descriptors/VnfdConnectionPointRef'
+import ConstituentVnfd from './descriptors/ConstituentVnfd'
+import ConstituentVnfdConnectionPoint from './descriptors/ConstituentVnfdConnectionPoint'
+import ForwardingGraph from './descriptors/ForwardingGraph'
+import InternalConnectionPoint from './descriptors/InternalConnectionPoint'
+import InternalVirtualLink from './descriptors/InternalVirtualLink'
+import NetworkService from './descriptors/NetworkService'
+import PhysicalNetworkFunction from './descriptors/PhysicalNetworkFunction'
+import RecordServicePath from './descriptors/RecordServicePath'
+import RspConnectionPointRef from './descriptors/RspConnectionPointRef'
+import VirtualDeploymentUnit from './descriptors/VirtualDeploymentUnit'
+import VirtualLink from './descriptors/VirtualLink'
+import VirtualNetworkFunction from './descriptors/VirtualNetworkFunction'
+import VirtualNetworkFunctionReadOnlyWrapper from './descriptors/VirtualNetworkFunctionReadOnlyWrapper'
+import InternalConnectionPointRef from './descriptors/InternalConnectionPointRef'
+import VirtualNetworkFunctionConnectionPoint from './descriptors/VirtualNetworkFunctionConnectionPoint'
+import VirtualDeploymentUnitInternalConnectionPoint from './descriptors/VirtualDeploymentUnitInternalConnectionPoint'
+
+function findChildDescriptorModelAndUpdateModel(model, parent) {
+       if (parent instanceof DescriptorModel) {
+               const child = parent.findChildByUid(model);
+               if (child) {
+                       child.model = model;
+                       return child;
+               }
+       }
+}
+
+let identity = 0;
+
+class DescriptorModelFactory {
+
+
+       static containerIdentity(d) {
+               const parentId = UID.from(d && d.parent);
+               // note the incremental counter is to always force d3 models to update
+               return (parentId ? parentId + ':' : '') + UID.from(d) + ':' + identity++;
+       }
+
+       /**
+        * Create a reduce function that creates a DescriptorModel element tree
+        * representation of a Catalog Item and then returns a flat list of
+        * DescriptorModel elements. The first item in the array is root.
+
+        * @returns {Function}
+        */
+       static buildCatalogItemFactory(catalogs) {
+
+               function findCatalogItemByTypeAndId(type, id) {
+                       return catalogs.filter(catalog => catalog.type === type).reduce((a, b) => a.concat(b.descriptors), []).filter(d => d.id === id)[0];
+               }
+
+               function mapVLD(vld, containerList) {
+                       containerList.push(vld);
+                       vld.connection.forEach(d => containerList.push(d));
+               }
+
+               function mapIVLD(ivld, containerList) {
+                       containerList.push(ivld);
+                       ivld.connection.forEach(d => containerList.push(d));
+               }
+
+               function mapRspConnectionPoint(cp, containerList) {
+                       containerList.push(cp);
+               }
+
+               function mapClassifier(classifier, containerList) {
+                       containerList.push(classifier);
+                       // get the referenced vnfd required for rendering the connection point
+                       const vnfdRef = findCatalogItemByTypeAndId('vnfd', classifier.model['vnfd-id-ref']);
+                       if (vnfdRef) {
+                               classifier.uiState.vnfdRef = vnfdRef;
+                       }
+                       classifier.matchAttributes.forEach(attr => containerList.push(attr));
+               }
+
+               function mapRSP(rsp, containerList) {
+                       containerList.push(rsp);
+                       rsp.vnfdConnectionPointRef.forEach(cpRef => mapRspConnectionPoint(cpRef, containerList));
+               }
+
+               function mapFG(fg, containerList) {
+                       containerList.push(fg);
+                       fg.rsp.forEach(rsp => mapRSP(rsp, containerList));
+                       fg.classifier.forEach(classifier => mapClassifier(classifier, containerList));
+               }
+
+               function mapVDU(vdu, containerList) {
+                       containerList.push(vdu);
+                       vdu.connectionPoint.forEach(d => containerList.push(d));
+               }
+
+               function mapCVNFD(cvnfd, containerList) {
+                       // get the referenced vnfd required for rendering the connection points
+                       const vnfdRef = findCatalogItemByTypeAndId('vnfd', cvnfd.model['vnfd-id-ref']);
+                       if (!vnfdRef) {
+                               console.warn('No VNFD found in catalog with id: ' + cvnfd['vnfd-id-ref']);
+                       }
+                       cvnfd.vnfdRef = vnfdRef;
+                       containerList.push(cvnfd);
+                       cvnfd.vld.forEach(vld => mapIVLD(vld, containerList));
+                       cvnfd.connectionPoint.forEach(cp => containerList.push(cp));
+               }
+
+               function mapNSD(nsd, containerList) {
+                       containerList.push(nsd);
+                       nsd.constituentVnfd.forEach(cvnfd => mapCVNFD(cvnfd, containerList));
+                       nsd.vld.forEach(vld => mapVLD(vld, containerList));
+                       nsd.vnffgd.forEach(fg => mapFG(fg, containerList));
+               }
+
+               function mapVNFD(vnfd, containerList) {
+                       containerList.push(vnfd);
+                       vnfd.vdu.forEach(vdu => mapVDU(vdu, containerList));
+                       vnfd.vld.forEach(vld => mapIVLD(vld, containerList));
+                       vnfd.connectionPoint.forEach(cp => containerList.push(cp));
+               }
+
+               function mapPNFD(pnfd, containerList) {
+                       containerList.push(pnfd);
+               }
+
+               return (containerList, obj) => {
+                       if (_.isEmpty(obj)) {
+                               return containerList;
+                       }
+                       switch (obj.uiState.type) {
+                       case 'nsd':
+                               mapNSD(DescriptorModelFactory.newNetworkService(obj), containerList);
+                               break;
+                       case 'vnfd':
+                               mapVNFD(DescriptorModelFactory.newVirtualNetworkFunction(obj), containerList);
+                               break;
+                       case 'pnfd':
+                               mapPNFD(DescriptorModelFactory.newPhysicalNetworkFunction(obj), containerList);
+                               break;
+                       default:
+                               throw new ReferenceError('only catalog items can be rendered in the canvas. unexpected type: ' + obj.uiState.type);
+                       }
+                       return containerList;
+               };
+
+       }
+
+       static newNetworkService(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new NetworkService(model, parent);
+       }
+
+       static newConstituentVnfd(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfd(model, parent);
+       }
+
+       static newVirtualNetworkFunction(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunction(model, parent);
+       }
+
+       static newVirtualNetworkFunctionConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualNetworkFunctionConnectionPoint(model, parent);
+       }
+
+       static newInternalConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalConnectionPoint(model, parent);
+       }
+
+       static newVirtualDeploymentUnit(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnit(model, parent);
+       }
+
+       static newVirtualDeploymentUnitInternalConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualDeploymentUnitInternalConnectionPoint(model, parent);
+       }
+
+       static newVirtualLink(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VirtualLink(model, parent);
+       }
+
+       static newInternalVirtualLink(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalVirtualLink(model, parent);
+       }
+
+       static newPhysicalNetworkFunction(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new PhysicalNetworkFunction(model, parent);
+       }
+
+       static newConstituentVnfdConnectionPoint(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ConstituentVnfdConnectionPoint(model, parent);
+       }
+
+       static newVnfdConnectionPointRef(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new VnfdConnectionPointRef(model, parent);
+       }
+
+       static newForwardingGraph(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ForwardingGraph(model, parent);
+       }
+
+       static newRecordServicePath(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new RecordServicePath(model, parent);
+       }
+
+       static newRspConnectionPointRef(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new RspConnectionPointRef(model, parent);
+       }
+
+       static newVirtualNetworkFunctionReadOnlyWrapper(vnfdToWrap, parent) {
+               let model;
+               if (vnfdToWrap instanceof DescriptorModel) {
+                       if (vnfdToWrap instanceof VirtualNetworkFunction) {
+                               model = vnfdToWrap.model;
+                       } else {
+                               throw new ReferenceError(`expected a VirtualNetworkFunction but got a ${vnfdToWrap.className}`);
+                       }
+               } else {
+                       model = vnfdToWrap;
+               }
+               return new VirtualNetworkFunctionReadOnlyWrapper(_.cloneDeep(model), parent);
+       }
+
+       static newClassifier(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new Classifier(model, parent);
+       }
+
+       static newClassifierMatchAttributes(model, parent) {
+               return findChildDescriptorModelAndUpdateModel(model, parent) || new ClassifierMatchAttributes(model, parent);
+       }
+
+       static newInternalConnectionPointRef(model, parent) {
+               // note do not find children bc model is not an object it is a leaf-list primative and so the class manages it
+               return new InternalConnectionPointRef(model, parent);
+       }
+
+       /**
+        * Special instance of a RecordServicePath that will create its parent ForwardingGraph it does not exist.
+        *
+        * This is useful to present a stub RSP as an initiator to create Paths without explicitly creating an RSP - just
+        * start building a path and it auto-magically builds the RSP.
+        *
+        * @param parent
+        * @param model
+        */
+       static newRecordServicePathFactory(model, parent) {
+               return new AutoCreateRecordServicePath(model, parent);
+       }
+
+       static isContainer(obj) {
+               return obj instanceof DescriptorModel;
+       }
+
+       static isConnector(obj) {
+               return obj instanceof ConnectionPoint;
+       }
+
+       static isConnectionPoint(obj) {
+               return obj instanceof ConnectionPoint;
+       }
+
+       static isConstituentVnfd(obj) {
+               return obj instanceof ConstituentVnfd;
+       }
+
+       static isConstituentVnfdWithServiceChain(obj, chain) {
+               return obj instanceof ConstituentVnfd && obj.vnfdServiceFunctionChain === chain;
+       }
+
+       static isNetworkService(obj) {
+               return obj instanceof NetworkService;
+       }
+
+       static isVnfdConnectionPointRef(obj) {
+               return obj instanceof VnfdConnectionPointRef;
+       }
+
+       static isRecordServicePath(obj) {
+               return obj instanceof RecordServicePath;
+       }
+
+       static isRspConnectionPointRef(obj) {
+               return obj instanceof RspConnectionPointRef;
+       }
+
+       static isVirtualLink(obj) {
+               return obj instanceof VirtualLink;
+       }
+
+       static isVirtualNetworkFunction(obj) {
+               return obj instanceof VirtualNetworkFunction;
+       }
+
+       static isForwardingGraph(obj) {
+               return obj instanceof ForwardingGraph;
+       }
+
+       static isInternalConnectionPoint(obj) {
+               return obj instanceof InternalConnectionPoint;
+       }
+
+       static isInternalVirtualLink(obj) {
+               return obj instanceof InternalVirtualLink;
+       }
+
+       static get VirtualLink () {
+               return VirtualLink;
+       }
+
+       static get NetworkService () {
+               return NetworkService;
+       }
+
+       static get ForwardingGraph () {
+               return ForwardingGraph;
+       }
+
+       static get VirtualNetworkFunction () {
+               return VirtualNetworkFunction;
+       }
+
+       static get ConstituentVnfd () {
+               return ConstituentVnfd;
+       }
+
+       static get Classifier() {
+               return Classifier;
+       }
+
+       static get ClassifierMatchAttributes() {
+               return ClassifierMatchAttributes;
+       }
+
+       static get VnfdConnectionPointRef() {
+               return VnfdConnectionPointRef;
+       }
+
+       static get VirtualDeploymentUnit() {
+               return VirtualDeploymentUnit;
+       }
+
+       static get InternalConnectionPoint() {
+               return InternalConnectionPoint;
+       }
+
+       static get InternalVirtualLink() {
+               return InternalVirtualLink;
+       }
+
+       static get InternalConnectionPointRef() {
+               return InternalConnectionPointRef;
+       }
+
+       static get VirtualNetworkFunctionConnectionPoint() {
+               return VirtualNetworkFunctionConnectionPoint;
+       }
+
+       static get VirtualDeploymentUnitInternalConnectionPoint() {
+               return VirtualDeploymentUnitInternalConnectionPoint;
+       }
+
+}
+
+/**
+ * Auto create a RecordServicePath when a VnfdConnectionPointRef is added.
+ */
+class AutoCreateRecordServicePath extends RecordServicePath {
+
+       constructor(model, parent) {
+               super(model, null);
+               this.parent = parent;
+               this.isFactory = true;
+       }
+
+       create() {
+               return this.parent.createRsp();
+       }
+
+       createVnfdConnectionPointRef(obj) {
+               const rsp = this.create();
+               rsp.createVnfdConnectionPointRef(obj);
+               return rsp;
+       }
+
+}
+
+export default DescriptorModelFactory;