updating .gitreview

Started integration with ONOS

Change-Id: Ibc85844f406e460875099336b30bb67708800165
diff --git a/mCordPortal/bs-config.js b/mCordPortal/bs-config.js
index dcf8ce3..f078e45 100644
--- a/mCordPortal/bs-config.js
+++ b/mCordPortal/bs-config.js
@@ -27,13 +27,16 @@
   target: conf.host || 'http://0.0.0.0:9999'
 });
 
+var onos_proxy = httpProxy.createProxyServer({
+  target: conf.onos_host || 'http://10.50.1.15:8181'
+});
+
 proxy.on('error', function(error, req, res) {
-  console.log('------------------------------------------------------');
-  // res.writeHead(500, {
-  //   'Content-Type': 'text/plain'
-  // });
   console.error('[Proxy]', error);
-  console.log('------------------------------------------------------');
+});
+
+onos_proxy.on('error', function(error, req, res) {
+  console.error('[ONOS Proxy]', error);
 });
 
 module.exports = {
@@ -68,6 +71,9 @@
         // console.log(`proxied: ${req.url}`, req.headers['x-csrftoken'], req.headers.cookie);
         proxy.web(req, res);
       }
+      else if(req.url.indexOf('/onos/') !== -1){
+        onos_proxy.web(req, res);
+      }
       else{
         next();
       }
diff --git a/mCordPortal/src/app/components/related-stats/related-stats.js b/mCordPortal/src/app/components/related-stats/related-stats.js
index 08bc813..48da617 100644
--- a/mCordPortal/src/app/components/related-stats/related-stats.js
+++ b/mCordPortal/src/app/components/related-stats/related-stats.js
@@ -36,7 +36,9 @@
           this.model.getStats()
           .then((stats) => {
             this.selectedStats = 'download_data';
-            this.stats = formatStats(stats.ProfileArray);
+            if(angular.isDefined(stats.ProfileArray)){
+              this.stats = formatStats(stats.ProfileArray);
+            }
           });
         };
 
diff --git a/mCordPortal/src/app/services/config.js b/mCordPortal/src/app/services/config.js
index 9bba19f..ae7adbd 100644
--- a/mCordPortal/src/app/services/config.js
+++ b/mCordPortal/src/app/services/config.js
@@ -1,9 +1,10 @@
 (function () {
   angular.module('mCord')
     .value('baseUrl', (function(){
-      if (process.env.MOCK === 'true') {
+      if (process.env.MOCK === 'apiary') {
         return 'http://private-c85424-progranrestapi.apiary-mock.com/';
-      } else {
+      }
+      else {
         return '';
       }
     })())
diff --git a/mCordPortal/src/app/services/rest/enodeb.js b/mCordPortal/src/app/services/rest/enodeb.js
index d1b9e50..aa28702 100644
--- a/mCordPortal/src/app/services/rest/enodeb.js
+++ b/mCordPortal/src/app/services/rest/enodeb.js
@@ -1,14 +1,32 @@
 (function () {
   angular.module('mCord')
-  .service('Enodeb', function($resource, $q, $http, baseUrl){
-    const r = $resource(`${baseUrl}api/enodeb/:id`, {id: '@eNBId'}, {
-      save: {method: 'PUT'}
+  .service('Enodeb', function($injector, $resource, $q, $http, baseUrl){
+    const r = $resource(`${baseUrl}onos/progran/enodeb/:id`, {id: '@eNBId'}, {
+      save: {method: 'PUT'},
+      query: {
+        array: false,
+        interceptor: {
+          response: function(res){
+            const Enodeb = $injector.get('Enodeb');
+            return res.data.EnodeBArray.map(n => new Enodeb(n));
+          }
+        }
+      },
+      get: {
+        array: false,
+        interceptor: {
+          response: function(res){
+            const Enodeb = $injector.get('Enodeb');
+            return new Enodeb(res.data.EnodeBArray[0]);
+          }
+        }
+      }
     });
 
     r.prototype.getProfiles = function(){
       const d = $q.defer();
 
-      $http.get(`${baseUrl}api/enodeb/${this.eNBId}/profile`)
+      $http.get(`${baseUrl}onos/progran/enodeb/${this.eNBId}/profile`)
       .then(res => {
         d.resolve(res.data);
       })
@@ -21,8 +39,7 @@
 
     r.prototype.getStats = function(){
       const d = $q.defer();
-
-      $http.get(`${baseUrl}api/stats/enodeb/${this.eNBId}/10`)
+      $http.get(`${baseUrl}onos/progran/stats/enodeb/${this.eNBId}/10`)
       .then(res => {
         d.resolve(res.data);
       })
diff --git a/mCordPortal/src/app/services/rest/imsi.js b/mCordPortal/src/app/services/rest/imsi.js
index 8e93aac..2359fe1 100644
--- a/mCordPortal/src/app/services/rest/imsi.js
+++ b/mCordPortal/src/app/services/rest/imsi.js
@@ -1,14 +1,32 @@
 (function () {
   angular.module('mCord')
-    .service('Imsi', function($resource, $q, $http, baseUrl){
-      const r = $resource(`${baseUrl}api/imsi/:id`, {id: '@IMSI'}, {
-        save: {method: 'PUT'}
+    .service('Imsi', function($injector, $resource, $q, $http, baseUrl){
+      const r = $resource(`${baseUrl}onos/progran/imsi/:id`, {id: '@IMSI'}, {
+        save: {method: 'PUT'},
+        query: {
+          array: false,
+          interceptor: {
+            response: function(res){
+              const Imsi = $injector.get('Imsi');
+              return res.data.ImsiArray.map(i => new Imsi(i));
+            }
+          }
+        },
+        get: {
+          array: false,
+          interceptor: {
+            response: function(res){
+              const Imsi = $injector.get('Imsi');
+              return new Imsi(res.data.ImsiArray[0]);
+            }
+          }
+        }
       });
 
       r.prototype.getProfiles = function(){
         const d = $q.defer();
 
-        $http.get(`${baseUrl}api/imsi/${this.IMSI}/profile`)
+        $http.get(`${baseUrl}onos/progran/imsi/${this.IMSI}/profile`)
           .then(res => {
             d.resolve(res.data);
           })
@@ -21,7 +39,7 @@
 
       r.prototype.deleteProfile = function(id){
         const d = $q.defer();
-        $http.delete(`${baseUrl}api/imsi/${this.IMSI}/profile/${id}`)
+        $http.delete(`${baseUrl}onos/progran/imsi/${this.IMSI}/profile/${id}`)
           .then(res => {
             d.resolve(res.data);
           })
diff --git a/mCordPortal/src/app/services/rest/profiles.js b/mCordPortal/src/app/services/rest/profiles.js
index a6e0d3c..6582784 100644
--- a/mCordPortal/src/app/services/rest/profiles.js
+++ b/mCordPortal/src/app/services/rest/profiles.js
@@ -1,12 +1,32 @@
 (function () {
   angular.module('mCord')
-  .service('Profile', function($resource, $q, $http, baseUrl){
-    const r = $resource(`${baseUrl}api/profile/:id`, {id: '@Name'});
+  .service('Profile', function($injector, $resource, $q, $http, baseUrl){
+    const r = $resource(`${baseUrl}onos/progran/profile/:id`, {id: '@Name'}, {
+      save: {method: 'PUT'},
+      query: {
+        array: false,
+        interceptor: {
+          response: function(res){
+            const Profile = $injector.get('Profile');
+            return res.data.ProfileArray.map(p => new Profile(p));
+          }
+        }
+      },
+      get: {
+        array: false,
+        interceptor: {
+          response: function(res){
+            const Profile = $injector.get('Profile');
+            return new Profile(res.data.ProfileArray[0]);
+          }
+        }
+      }
+    });
 
     r.prototype.getImsis = function(){
       const d = $q.defer();
 
-      $http.get(`${baseUrl}api/profile/${this.Name}/imsi`)
+      $http.get(`${baseUrl}onos/progran/profile/${this.Name}/imsi`)
       .then(res => {
         d.resolve(res.data);
       })
@@ -20,7 +40,7 @@
     r.prototype.deleteImsis = function(){
       const d = $q.defer();
 
-      $http.delete(`${baseUrl}api/profile/${this.Name}/imsi`)
+      $http.delete(`${baseUrl}onos/progran/profile/${this.Name}/imsi`)
       .then(res => {
         d.resolve(res.data);
       })
@@ -34,7 +54,7 @@
     r.prototype.deleteImsi = function(id){
       const d = $q.defer();
 
-      $http.delete(`${baseUrl}api/profile/${this.Name}/imsi/${id}`)
+      $http.delete(`${baseUrl}onos/progran/profile/${this.Name}/imsi/${id}`)
       .then(res => {
         d.resolve(res.data);
       })
@@ -48,7 +68,7 @@
     r.prototype.getEnodes = function(){
       const d = $q.defer();
 
-      $http.get(`${baseUrl}api/profile/${this.Name}/enodeb`)
+      $http.get(`${baseUrl}onos/progran/profile/${this.Name}/enodeb`)
       .then(res => {
         d.resolve(res.data);
       })
@@ -62,7 +82,7 @@
     r.prototype.deleteEnodes = function(){
       const d = $q.defer();
 
-      $http.delete(`${baseUrl}api/profile/${this.Name}/enodeb`)
+      $http.delete(`${baseUrl}onos/progran/profile/${this.Name}/enodeb`)
       .then(res => {
         d.resolve(res.data);
       })
@@ -76,7 +96,7 @@
     r.prototype.deleteEnode = function(id){
       const d = $q.defer();
 
-      $http.delete(`${baseUrl}api/profile/${this.Name}/enodeb/${id}`)
+      $http.delete(`${baseUrl}onos/progran/profile/${this.Name}/enodeb/${id}`)
       .then(res => {
         d.resolve(res.data);
       })
diff --git a/mCordPortal/src/app/services/users.js b/mCordPortal/src/app/services/users.js
index ebce988..5d4866d 100644
--- a/mCordPortal/src/app/services/users.js
+++ b/mCordPortal/src/app/services/users.js
@@ -58,8 +58,9 @@
       .then(function(subscribers){
         // subscribers are an array because the way Django perform query
         // but one user is related to only one subscriber
-
-        $cookies.put('subscriberId', subscribers.data[0].id);
+        if(subscribers.data[0]){
+          $cookies.put('subscriberId', subscribers.data[0].id);
+        }
         deferred.resolve(user);
       })
       .catch(function(e){
diff --git a/mCordPortal/src/app/view/home/e-node-map.js b/mCordPortal/src/app/view/home/e-node-map.js
index b3818e7..423a5c7 100644
--- a/mCordPortal/src/app/view/home/e-node-map.js
+++ b/mCordPortal/src/app/view/home/e-node-map.js
@@ -15,12 +15,13 @@
 
           Enodeb.query().$promise
           .then((enodes) => {
-            console.log('loaded enodes for map');
             this.enodes = enodes;
             bounds = new google.maps.LatLngBounds();
             enodes.forEach(node => {
-              const latlng = new google.maps.LatLng(node.GpsCoordinate.Latitude, node.GpsCoordinate.Longitude);
-              bounds.extend(latlng);
+              if(angular.isDefined(node.GpsCoordinate.Latitude) && angular.isDefined(node.GpsCoordinate.Longitude)){
+                const latlng = new google.maps.LatLng(node.GpsCoordinate.Latitude, node.GpsCoordinate.Longitude);
+                bounds.extend(latlng);
+              }
             });
             return NgMap.getMap();
           })
diff --git a/mCordPortal/src/app/view/home/e-node-map.tpl.html b/mCordPortal/src/app/view/home/e-node-map.tpl.html
index afe6735..2c1dd95 100644
--- a/mCordPortal/src/app/view/home/e-node-map.tpl.html
+++ b/mCordPortal/src/app/view/home/e-node-map.tpl.html
@@ -1,7 +1,7 @@
 <ng-map center="[0, 0]" map-type-control="false" street-view-control="false" zoom-control="false" scale-control="false">
   <marker 
-    ng-repeat="enode in vm.enodes" 
-    position="[{{enode.GpsCoordinate.Latitude}}, {{enode.GpsCoordinate.Longitude}}]" 
+    ng-repeat="enode in vm.enodes"
+    position="[{{enode.GpsCoordinate.Latitude}}, {{enode.GpsCoordinate.Longitude}}]"
     on-click="vm.showEnodeDetails(enode)"
     no-watcher="false"></marker>
 </ng-map>
diff --git a/mCordPortal/src/app/view/profiles-details/profiles-details.js b/mCordPortal/src/app/view/profiles-details/profiles-details.js
index 124db00..4f03dcd 100644
--- a/mCordPortal/src/app/view/profiles-details/profiles-details.js
+++ b/mCordPortal/src/app/view/profiles-details/profiles-details.js
@@ -16,30 +16,170 @@
         controllerAs: 'vm',
         templateUrl: 'app/view/profiles-details/profiles-details.tpl.html',
         controller: function ($uibModal, $stateParams, Profile, _) {
-          Profile.get({id: $stateParams.id}).$promise
-          .then((profile) => {
-            this.profile = profile;
-            return $q.all([
-              profile.getImsis(),
-              profile.getEnodes()
-            ]);
-          })
-          .then(res => {
-            const [imsis, enodes] = res;
-            this.imsis = imsis;
-            this.enodes = enodes;
-          })
-          .catch(e => console.log(e));
+          this.isNew = true;
+          if($stateParams.id){
+            Profile.get({id: $stateParams.id}).$promise
+            .then((profile) => {
+              this.profile = profile;
+              this.isNew = false;
+              this.formConfig.actions[0].label = 'Update';
+              return $q.all([
+                profile.getImsis(),
+                profile.getEnodes()
+              ]);
+            })
+            .then(res => {
+              const [imsis, enodes] = res;
+              this.imsis = imsis;
+              this.enodes = enodes;
+            })
+            .catch(e => console.log(e));
+          }
+          else {
+            this.profile = new Profile();
+            this.imsis = [];
+            this.enodes = [];
+          }
+
+          const UD_Types = [
+            {id: 'RR', label: 'RR'},
+            {id: 'PF', label: 'PF'},
+            {id: 'MAXCI', label: 'MAXCI'}
+          ];
 
           this.formConfig = {
             exclude: ['IMSIRuleArray'],
             formName: 'updateProfiles',
+            fields: {
+              Name: {
+                type: 'string',
+                validator: {
+                  required: true
+                }
+              },
+              DlSchedType: {
+                type: 'select',
+                validator: {
+                  required: true
+                },
+                options: UD_Types
+              },
+              DlAllocRBRate: {
+                type: 'number',
+                validator: {
+                  required: true
+                }
+              },
+              UlSchedType: {
+                type: 'select',
+                validator: {
+                  required: true
+                },
+                options: UD_Types
+              },
+              UlAllocRBRate: {
+                type: 'number',
+                validator: {
+                  required: true
+                }
+              },
+              Start: {
+                type: 'date',
+                validator: {
+                  required: true
+                }
+              },
+              End: {
+                type: 'date',
+                validator: {
+                  required: true
+                }
+              },
+              AdmControl: {
+                type: 'select',
+                validator: {
+                  required: true
+                },
+                options: [
+                  {id: 0, label: 'All'},
+                  {id: 1, label: 'Voice Only'},
+                  {id: 2, label: 'Data Only'}
+                ]
+              },
+              CellIndividualOffset: {
+                type: 'number',
+                validator: {
+                  required: true
+                }
+              },
+              Handover: {
+                type: 'object',
+                properties: {
+                  A3offset: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  HysteresisA3: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  A5TriggerType: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  A5Thresh1Rsrp: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  A5Thresh1Rsrq: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  A5Thresh2Rsrp: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  A5Thresh2Rsrq: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                  HysteresisA5: {
+                    type: 'number',
+                    validator: {
+                      required: true
+                    }
+                  },
+                }
+              }
+            },
             actions: [
               {
-                label: 'Update',
+                label: 'Save',
                 icon: 'ok',
-                cb: (imsi) => {
-                  imsi.$save();
+                cb: (profile) => {
+                  if(this.isNew){
+                    Profile.save(profile).$promise
+                    .then((profile) => {
+                      // TODO save imsi and enodes
+                    });
+                  }
+                  else{
+                    profile.$save();
+                  }
                 },
                 class: 'primary-border'
               }
@@ -142,6 +282,7 @@
               controller: function ($uibModalInstance) {
                 this.modal    = $uibModalInstance;
                 this.callback = (imsi) => {
+                  // TODO call BE (if !this.isNew)
                   _this.imsis.push(imsi);
                 };
                 this.profile = _this.profile;
@@ -158,6 +299,7 @@
               controller: function ($uibModalInstance) {
                 this.modal    = $uibModalInstance;
                 this.callback = (enode) => {
+                  // TODO call BE (if !this.isNew)
                   _this.enodes.push(enode);
                 };
                 this.profile = _this.profile;
diff --git a/mCordPortal/src/app/view/profiles-list/profiles-list.tpl.html b/mCordPortal/src/app/view/profiles-list/profiles-list.tpl.html
index f1c17f6..b02b98b 100644
--- a/mCordPortal/src/app/view/profiles-list/profiles-list.tpl.html
+++ b/mCordPortal/src/app/view/profiles-list/profiles-list.tpl.html
@@ -1,3 +1,8 @@
 <div class="container-fluid">
+    <div class="row">
+        <div class="col-xs-12 text-right">
+            <a ui-sref="profile-details" class="btn btn-success">Add Profile</a>
+        </div>
+    </div>
     <xos-table config="vm.tableConfig" data="vm.profiles"></xos-table>
 </div>
\ No newline at end of file