Moving metro-net to vnaas and porting to 4.0

Change-Id: Id42bb247033087e5d28bcbab9db07d58e6364625
(cherry picked from commit 95c02bd391ad5eb8edeba00e81b851b97a6abbd1)
diff --git a/xos/gui/src/app/components/eline-side.component.html b/xos/gui/src/app/components/eline-side.component.html
new file mode 100755
index 0000000..e0c19f0
--- /dev/null
+++ b/xos/gui/src/app/components/eline-side.component.html
@@ -0,0 +1,64 @@
+
+<!--
+Copyright 2017-present Open Networking Foundation
+
+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.
+-->
+
+<div class = "elinepanel">
+  <h1>ELine Overview</h1>
+  <form ng-submit="vm.saveEline(vm.eng.eline)">
+    <div class="form-group" ng-hide="vm.eng.createMode">
+      <label>ID</label><br/>
+      <p>{{vm.eng.eline.id}}</p>
+    </div>
+    <div class="form-group">
+      <label for="name">Name</label>
+      <input required class="form-control" id="name" type="text" ng-value="vm.eng.eline.name" ng-model="vm.eng.eline.name">
+    </div>
+    <div class="form-group" ng-hide="vm.eng.createMode">
+      <label>Backend Status</label><br/>
+      <p>{{vm.eng.eline.backend_status}}</p>
+    </div>
+    <div class="form-group">
+      <label for="cpi1">Connect point 1 ID</label>
+      <input required class="form-control" id="cpi1" type="text" ng-value="vm.eng.eline.connect_point_1_id" ng-model="vm.eng.eline.connect_point_1_id">
+    </div>
+    <div class="form-group">
+      <label for="cpi2">Connect point 2 ID</label>
+      <input required class="form-control" id="cpi2" type="text" ng-value="vm.eng.eline.connect_point_2_id" ng-model="vm.eng.eline.connect_point_2_id">
+    </div>
+    <div class="form-group">
+      <label for="bwps">Bandwidth Profile</label>
+      <select required class="form-control"
+              id="bwps"
+              ng-model="vm.eng.eline.bwp"
+              ng-options="bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'"
+      >
+      </select>
+    </div>
+    <div class="form-group">
+      <label for="sitename">CORD Site Name</label>
+      <input required class="form-control" id="sitename" type="text" ng-value="vm.eng.eline.cord_site_name" ng-model="vm.eng.eline.cord_site_name">
+    </div>
+    <div class="form-group">
+      <label for="vlanids">Vlan IDs</label>
+      <input required class="form-control" id="vlanids" type="text" ng-value="vm.eng.eline.vlanids" ng-model="vm.eng.eline.vlanids">
+    </div>
+    <div class="form-group" style="text-align: center">
+      <button type="submit" class="btn btn-success btn-block">Save Changes</button>
+    </div>
+  </form>
+  <button type="button" class="btn btn-danger btn-block" ng-click="vm.eng.elinePanel({}, vm.eng.eline, false)">Close</button>
+  <button type="button" class="btn btn-danger delete-eline" ng-click="vm.deleteEline(vm.eng.eline)">Delete Eline</button>
+</div>
\ No newline at end of file
diff --git a/xos/gui/src/app/components/eline-side.component.ts b/xos/gui/src/app/components/eline-side.component.ts
new file mode 100755
index 0000000..fb8a2f1
--- /dev/null
+++ b/xos/gui/src/app/components/eline-side.component.ts
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+let self;
+
+class ElineSide {
+
+  static $inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];
+
+  constructor(
+    private XosSidePanel: any,
+    private XosModelStore: any,
+    private $http: any,
+    private $log: any,
+    private toastr: any,
+  ) {
+    self = this;
+  }
+
+  public saveEline(item: any) {
+    let path = item.path;
+    delete item.path;
+    item.$save().then((res) => {
+      item.path = path;
+      this.toastr.success(`${item.name} successfully saved!`);
+    })
+      .catch((error) => {
+        this.toastr.error(`Error while saving ${item.name}: ${error.specific_error}`);
+      });
+  }
+
+  public deleteEline(item: any) {
+    let name = item.name;
+    item.$delete().then((res) => {
+      this.toastr.success(`${name} successfully deleted!`);
+    })
+    .catch((error) => {
+        this.toastr.error(`Error while deleting ${name}: ${error.specific_error}`);
+      });
+  }
+
+
+}
+
+export const elineSide: angular.IComponentOptions = {
+  template: require('./eline-side.component.html'),
+  controllerAs: 'vm',
+  controller: ElineSide,
+  bindings: {
+    eng: '='
+  }
+};
diff --git a/xos/gui/src/app/components/engMap.component.html b/xos/gui/src/app/components/engMap.component.html
new file mode 100755
index 0000000..cf85835
--- /dev/null
+++ b/xos/gui/src/app/components/engMap.component.html
@@ -0,0 +1,78 @@
+
+<!--
+Copyright 2017-present Open Networking Foundation
+
+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.
+-->
+
+
+<div class = "row">
+  <div class = "col-xs-12">
+    <h1>Enterprise Network Map</h1>
+    <div map-lazy-load="https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4">
+      <ng-map
+        default-style="false"
+        id="foobar"
+        center="0,0"
+        disable-default-u-i="true"
+        map-type-id="ROADMAP"
+        zoom-control="true"
+        min-zoom="2"
+        styles="{{vm.mapStyles}}"
+      >
+        <!--Markers-->
+        <marker
+          ng-repeat="uni in vm.unis"
+          id="marker-{{uni.id}}"
+          position="{{uni.latlng.toString()}}"
+          icon="{{vm.MapConfig.marker}}"
+          on-click="vm.showUni(uni)"
+        >
+        </marker>
+
+        <!--Marker Info Window-->
+
+        <info-window id = "uni-info">
+          <div class = "marker-info">
+            <h4>{{vm.current_uni.name}}</h4>
+            <p>
+              <b>LatLng: </b>{{vm.current_uni.latlng.toString()}}<br/>
+              <b>Cpe id: </b>{{vm.current_uni.cpe_id}}<br/>
+              <b>Tenant: </b>{{vm.current_uni.tenant}}<br/>
+            </p>
+            <button ng-show="vm.canCreateEline" ng-click="vm.createConnection(vm.current_uni)()">Create connection</button>
+            <button ng-show="!vm.canCreateEline && !uni.eline_start" ng-click="vm.finishConnection(vm.current_uni)">Finish connection</button>
+          </div>
+        </info-window>
+
+        <!--Connections-->
+
+        <shape
+          ng-repeat="eline in vm.elines"
+          name="polyline"
+          id="eline-{{eline.id}}"
+          path="{{eline.path}}"
+          stroke-color="{{vm.colorLine(eline.backend_status)}}"
+          stroke-opacity="1.0"
+          stroke-weight="5"
+          on-click="vm.elinePanel({{eline}}, true)"
+        >
+        </shape>
+
+      </ng-map>
+
+    </div>
+    Changes may not display until page refresh.
+  </div>
+</div>
+<!--"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4"-->
\ No newline at end of file
diff --git a/xos/gui/src/app/components/engMap.component.ts b/xos/gui/src/app/components/engMap.component.ts
new file mode 100755
index 0000000..1f726c8
--- /dev/null
+++ b/xos/gui/src/app/components/engMap.component.ts
@@ -0,0 +1,198 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+import {NgMap} from 'ngmap';
+import {Subscription} from 'rxjs/Subscription';
+import * as _ from 'lodash';
+
+declare var google;
+
+let self;
+
+export class EngMap {
+
+  static $inject = [
+    'NgMap',
+    'XosModelStore',
+    'AppConfig',
+    '$resource',
+    'XosSidePanel',
+    'XosModelDiscoverer',
+    'ModelRest',
+    'MapConfig',
+  ];
+
+  public unis = [];
+  public elines = [];
+  public cpilatlng = new Map();
+  public paths = [];
+  public bwps = [];
+  public map;
+  public panelOpen = false;
+  public createMode = false;
+  public canCreateEline = true;
+  public eline;
+  public current_uni;
+  public mapStyles = [{'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{'color': '#444444'}]}, {'featureType': 'landscape', 'elementType': 'all', 'stylers': [{'color': '#f2f2f2'}]}, {'featureType': 'poi', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'road', 'elementType': 'all', 'stylers': [{'saturation': -100}, {'lightness': 45}]}, {'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{'visibility': 'simplified'}]}, {'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'transit', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'water', 'elementType': 'all', 'stylers': [{'color': '#9ce1fc'}, {'visibility': 'on'}]}];
+
+  private uniSubscription: Subscription;
+  private elineSubscription: Subscription;
+  private bwpSubscription: Subscription;
+
+  constructor(
+    private NgMap: any,
+    private XosModelStore: any,
+    private AppConfig: any,
+    private $resource: any,
+    private XosSidePanel: any,
+    private XosModelDiscoverer: any,
+    private ModelRest: any,
+    private MapConfig: any,
+  ) {
+    self = this;
+  }
+
+  $onInit() {
+    this.NgMap.getMap().then(map => {
+      this.map = map;
+      this.uniSubscription = this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(
+        res => {
+          this.unis = res;
+          this.renderMap(map);
+        }
+      );
+      this.elineSubscription = this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(
+        res => {
+          this.elines = res;
+          this.createPaths();
+          this.renderMap(map);
+        }
+      );
+      this.bwpSubscription = this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(
+        res => {
+          this.bwps = res;
+        }
+      );
+    });
+  }
+
+  $onDestroy() {
+    if (this.uniSubscription) {
+      this.uniSubscription.unsubscribe();
+    }
+  }
+
+  public renderMap(map: NgMap) {
+
+    let bounds = new google.maps.LatLngBounds();
+
+    for (let i = 0; i < self.unis.length; i++) {
+      self.unis[i].eline_start = false;
+      let curr = JSON.parse(self.unis[i].latlng);
+      this.cpilatlng.set(self.unis[i].cpe_id, curr);
+      let latlng = new google.maps.LatLng(curr[0], curr[1]);
+      bounds.extend(latlng);
+    }
+    map.setCenter(bounds.getCenter());
+    map.fitBounds(bounds);
+
+  }
+
+  public createPaths() {
+    this.elines.forEach((eline: any) => {
+      let latlng_start = this.cpilatlng.get(eline.connect_point_1_id);
+      let latlng_end = this.cpilatlng.get(eline.connect_point_2_id);
+      eline.path = [latlng_start, latlng_end];
+    });
+
+  }
+
+  public colorLine(eline_status : any) {
+    let status = parseInt(eline_status, 10);
+    switch (status) {
+      case 0:
+        return '#f39c12';
+      case 1:
+        return '#2ecc71';
+      default:
+        return '#e74c3c';
+    }
+
+  }
+
+  public showUni(e: any, uni: any) {
+    self.current_uni = uni;
+    self.map.showInfoWindow('uni-info', this);
+  }
+
+  // do not display backend status or ID in create mode
+
+  public elinePanel(e: any, eline: any, exists: boolean) {
+    self.panelOpen = !self.panelOpen;
+    if (exists) {
+      self.eline = _.find(self.elines, {id: eline.id});
+    }
+    self.XosSidePanel.toggleComponent('elineSide', {eline: self.eline, bwplist: self.bwps, eng: self}, false);
+    if (!self.panelOpen && self.createMode) {
+      self.createMode = false;
+      self.canCreateEline = true;
+      self.current_uni.eline_start = false;
+    }
+
+  }
+
+  public createConnection(uni: any) {
+    return () => {
+      self.canCreateEline = false;
+      self.createMode = true;
+      uni.eline_start = true;
+      self.current_uni = uni;
+      self.eline = {
+        name: uni.name,
+        uni1name: uni.name,
+        connect_point_1_id: uni.cpe_id,
+      };
+      self.elinePanel({}, self.eline, false);
+    };
+
+  }
+
+  public finishConnection(uni: any) {
+    self.eline.connect_point_2_id = uni.cpe_id;
+    if (self.eline.name === self.eline.uni1name) {
+      self.eline.name = self.eline.name + uni.name;
+    }
+    delete self.eline.uni1name;
+    const resource = this.ModelRest.getResource('/vnaas/elines/');
+    let res = new resource({});
+    for (let attr in self.eline) {
+      if (true) {
+        res[attr] = self.eline[attr];
+      }
+
+    }
+    self.eline = res;
+  }
+
+}
+
+export const engMap: angular.IComponentOptions = {
+  template: require('./engMap.component.html'),
+  controllerAs: 'vm',
+  controller: EngMap,
+};
diff --git a/xos/gui/src/app/img/co.png b/xos/gui/src/app/img/co.png
new file mode 100755
index 0000000..3f07a6a
--- /dev/null
+++ b/xos/gui/src/app/img/co.png
Binary files differ
diff --git a/xos/gui/src/app/style/style.css b/xos/gui/src/app/style/style.css
new file mode 100755
index 0000000..44f2f1b
--- /dev/null
+++ b/xos/gui/src/app/style/style.css
@@ -0,0 +1,41 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+ng-map, [map-lazy-load]{
+    height: 600px;
+    width: 100%;
+}
+
+.marker-info > *{
+    color: #000000;
+}
+
+body > ui-view > xos > div > xos-side-panel > section > div:nth-child(1) {
+    display: none;
+}
+
+.elinepanel{
+    height: 100%;
+}
+
+.delete-eline{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    margin: 10px;
+}
\ No newline at end of file