From e987bbc8bbfdae58e8cccd283940104d1955b10c Mon Sep 17 00:00:00 2001
From: blavenie <benoit.lavenier@e-is.pro>
Date: Thu, 26 Jan 2017 19:15:11 +0100
Subject: [PATCH] ES settings: select ES node by endpoint

---
 www/js/controllers/settings-controllers.js    | 25 +++----
 www/js/services/bma-services.js               | 20 ++++++
 www/js/services/network-services.js           | 18 +----
 .../es/js/controllers/settings-controllers.js | 72 ++++++++++++++-----
 www/plugins/es/js/services/user-services.js   | 29 +++++++-
 5 files changed, 110 insertions(+), 54 deletions(-)

diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index 5391f095a..09b84bfc4 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -79,7 +79,7 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
       }
       UIUtils.loading.show();
       var nodeBMA = BMA.instance(newNode.host, newNode.port);
-      nodeBMA.node.summary() // ping the node
+      api.node.summary() // ping the node
       .then(function() {
         UIUtils.loading.hide();
         $scope.formData.node = newNode;
@@ -98,21 +98,14 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
   $scope.showNodeList = function() {
     $ionicPopup._popupStack[0].responseDeferred.promise.close();
     return Modals.showNetworkLookup({enableFilter: true, type: 'member'})
-      .then(function (result) {
-        if (result) {
-          var parts = result.server.split(':');
-          if (result.dns) {
-            return {
-              host: result.dns,
-              port: parts[1] || 80
-            };
-          }
-          else {
-            return {
-              host: parts[0],
-              port: parts[1] || 80
-            };
-          }
+      .then(function (peer) {
+        if (peer) {
+          var bma = peer.getBMA();
+          return {
+            host: (bma.dns ? bma.dns :
+                   (peer.hasValid4(bma) ? bma.ipv4 : bma.ipv6)),
+            port: bma.port || 80
+          };
         }
       })
       .then(function(newNode) {
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index eae9bdedb..0122ba799 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -65,6 +65,7 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
       },
       network: {
         peering: {
+          self: csHttp.get(host, port, '/network/peering'),
           peers: csHttp.get(host, port, '/network/peering/peers')
         },
         peers: csHttp.get(host, port, '/network/peers')
@@ -114,6 +115,25 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce
       }
     };
 
+    exports.lightInstance = function(host, port) {
+      return {
+        node: {
+          summary: csHttp.getWithCache(host, port, '/node/summary', csHttp.cache.LONG)
+        },
+        network: {
+          peering: {
+            self: csHttp.get(host, port, '/network/peering')
+          }
+        },
+        blockchain: {
+          current: csHttp.get(host, port, '/blockchain/current'),
+          stats: {
+            hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey')
+          }
+        }
+      };
+    };
+
     exports.node.parseEndPoint = function(endpoint) {
       var matches = exports.regex.BMA_ENDPOINT.exec(endpoint);
       if (!matches) return;
diff --git a/www/js/services/network-services.js b/www/js/services/network-services.js
index ed997f6c8..3d1ab49dc 100644
--- a/www/js/services/network-services.js
+++ b/www/js/services/network-services.js
@@ -70,20 +70,6 @@ angular.module('cesium.network.services', ['ngResource', 'ngApi', 'cesium.bma.se
         return data.knownBlocks;
       },
 
-      newLightBMA = function(host, port) {
-        return {
-          node: {
-            summary: csHttp.getWithCache(host, port, '/node/summary', csHttp.cache.LONG)
-          },
-          blockchain: {
-            current: csHttp.get(host, port, '/blockchain/current'),
-            stats: {
-              hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey')
-            }
-          }
-        };
-      },
-
       loadPeers = function() {
         data.peers = [];
         data.searchingPeersOnNetwork = true;
@@ -239,7 +225,7 @@ angular.module('cesium.network.services', ['ngResource', 'ngApi', 'cesium.bma.se
         // Apply filter
         if (!applyPeerFilter(peer)) return $q.when();
 
-        peer.api = peer.api || newLightBMA(peer.getHost(), peer.getPort());
+        peer.api = peer.api || BMA.lightInstance(peer.getHost(), peer.getPort());
 
         // Get current block
         return peer.api.blockchain.current()
@@ -266,7 +252,7 @@ angular.module('cesium.network.services', ['ngResource', 'ngApi', 'cesium.bma.se
               if (bma.dns && peer.server.indexOf(bma.dns) == -1) {
                 // try again, using DNS instead of IPv4 / IPV6
                 peer.secondTry = true;
-                peer.api = newLightBMA(bma.dns, bma.port);
+                peer.api = BMA.lightInstance(bma.dns, bma.port);
                 return refreshPeer(peer); // recursive call
               }
             }
diff --git a/www/plugins/es/js/controllers/settings-controllers.js b/www/plugins/es/js/controllers/settings-controllers.js
index be768c7f4..c78a9055f 100644
--- a/www/plugins/es/js/controllers/settings-controllers.js
+++ b/www/plugins/es/js/controllers/settings-controllers.js
@@ -48,8 +48,7 @@ function ESExtendSettingsController ($scope, PluginService, csSettings) {
 /*
  * Settings extend controller
  */
-function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUtils, csSettings, csHttp, esMarket,
-  esRegistry, esUser) {
+function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUtils, Modals, esHttp, csSettings, csHttp, esUser) {
   'ngInject';
 
   $scope.formData = {};
@@ -74,26 +73,32 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
   // Change ESnode
   $scope.changeEsNode= function(node) {
     $scope.showNodePopup(node || $scope.formData)
-    .then(function(node) {
-      if (node.host === $scope.formData.host &&
-        node.port === $scope.formData.port) {
+    .then(function(newNode) {
+      if (newNode.host === $scope.formData.host &&
+        newNode.port === $scope.formData.port) {
+        UIUtils.loading.hide();
         return; // same node = nothing to do
       }
       UIUtils.loading.show();
 
-      var newInstance = esMarket.instance(node.host, node.port);
-      esMarket.copy(newInstance);
-
-      newInstance = esRegistry.instance(node.host, node.port);
-      esRegistry.copy(newInstance);
-
-      newInstance = esUser.instance(node.host, node.port);
-      esUser.copy(newInstance);
-
-      $scope.formData.host = node.host;
-      $scope.formData.port = node.port;
-
-      UIUtils.loading.hide(10);
+      return esHttp.get(newNode.host, newNode.port, '/node/summary')() // ping the node
+        .then(function(json) {
+          var valid = json && json.duniter && json.duniter.software === 'duniter4j-elasticsearch';
+          if (!valid) throw 'stop';
+
+          UIUtils.loading.hide();
+          $scope.formData.host = newNode.host;
+          $scope.formData.port = newNode.port;
+          esUser.copy(esUser.instance('default', newNode.host, newNode.port));
+
+        })
+        .catch(function(err) {
+          UIUtils.loading.hide();
+          UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY')
+            .then(function(){
+              $scope.changeEsNode(newNode); // loop
+            });
+        });
     });
   };
 
@@ -138,13 +143,42 @@ function ESPluginSettingsController ($scope, $q,  $translate, $ionicPopup, UIUti
             parts[1] = parts[1] ? parts[1] : 80;
             resolve({
               host: parts[0],
-              port: parts[1] || 80
+              port: parts[1]
             });
           });
         });
     });
   };
 
+  $scope.showNodeList = function() {
+    $ionicPopup._popupStack[0].responseDeferred.promise.close();
+    return Modals.showNetworkLookup({
+      enableFilter: true,
+      endpointFilter: esUser.constants.ES_USER_API_ENDPOINT
+    })
+      .then(function (peer) {
+        if (!peer) return;
+          var esEps = peer.getEndpoints().reduce(function(res, ep){
+            var esEp = esUser.node.parseEndPoint(ep);
+            return esEp ? res.concat(esEp) : res;
+          }, []);
+          if (!esEps.length) return;
+          var ep = esEps[0];
+          return {
+            host: (ep.dns ? ep.dns :
+                   (peer.hasValid4(ep) ? ep.ipv4 : ep.ipv6)),
+            port: ep.port || 80
+          };
+      })
+      .then(function(newEsNode) {
+        if (!newEsNode) {
+          UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY');
+          return;
+        }
+        $scope.changeEsNode(newEsNode);
+      });
+  };
+
   $scope.onFormChanged = function() {
     if ($scope.loading) return;
 
diff --git a/www/plugins/es/js/services/user-services.js b/www/plugins/es/js/services/user-services.js
index 333048e7b..b144e18e0 100644
--- a/www/plugins/es/js/services/user-services.js
+++ b/www/plugins/es/js/services/user-services.js
@@ -17,7 +17,11 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se
 
     var
       CONSTANTS = {
-        contentTypeImagePrefix: "image/"
+        contentTypeImagePrefix: "image/",
+        ES_USER_API_ENDPOINT: "ES_USER_API( ([a-z_][a-z0-9-_.]*))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))"
+      },
+      REGEX = {
+        ES_USER_API_ENDPOINT: exact(CONSTANTS.ES_USER_API_ENDPOINT)
       },
       FIELDS = {
         avatar: ['title', 'avatar._content_type']
@@ -42,6 +46,10 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se
       getRequest = esHttp.get(host, port, '/user/profile/:id?&_source_exclude=avatar._content')
     ;
 
+    function exact(regexpContent) {
+      return new RegExp("^" + regexpContent + "$");
+    }
+
     function copy(otherNode) {
       removeListeners();
       if (!!this.instance) {
@@ -52,6 +60,7 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se
       else {
         angular.copy(otherNode, this);
       }
+      addListeners();
     }
 
     function copyUsingSpec(data, copySpec) {
@@ -503,6 +512,17 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se
       }
     }
 
+    function parseEndPoint(endpoint) {
+      var matches = REGEX.ES_USER_API_ENDPOINT.exec(endpoint);
+      if (!matches) return;
+      return {
+        "dns": matches[2] || '',
+        "ipv4": matches[4] || '',
+        "ipv6": matches[6] || '',
+        "port": matches[8] || 80
+      };
+    }
+
     // Listen for settings changed
     csSettings.api.data.on.changed($rootScope, function(data){
       if (restoringSettings) {
@@ -549,7 +569,9 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se
     return {
       copy: copy,
       node: {
-        server: esHttp.getServer(host, port)
+        server: esHttp.getServer(host, port),
+        summary: esHttp.get(host, port, '/node/summary'),
+        parseEndPoint: parseEndPoint
       },
       profile: {
         get: esHttp.get(host, port, '/user/profile/:id'),
@@ -570,7 +592,8 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se
         change: function() {
           return esHttp.ws('ws://'+esHttp.getServer(host, wsPort)+'/ws/_changes');
         }
-      }
+      },
+      constants: CONSTANTS
     };
   }
 
-- 
GitLab