From 5fae2dc7762d851505cee66c96a3d796fbfc382f Mon Sep 17 00:00:00 2001
From: Adhidarma Hadiwinoto <me@adhisimon.org>
Date: Fri, 21 Jun 2019 13:36:40 +0700
Subject: [PATCH] Checking core version

---
 index.js                     |  4 ++++
 lib/command-handler/error.js |  3 ++-
 lib/coreapi/core-version.js  | 48 +++++++++++++++++++++++++++++++++++++
 lib/coreapi/index.js         | 57 ++++++++------------------------------------
 lib/coreapi/matrix.js        | 17 +++++++++++++
 lib/coreapi/request.js       | 57 ++++++++++++++++++++++++++++++++++++++++++++
 package-lock.json            |  5 ++++
 package.json                 |  1 +
 8 files changed, 144 insertions(+), 48 deletions(-)
 create mode 100644 lib/coreapi/core-version.js
 create mode 100644 lib/coreapi/matrix.js
 create mode 100644 lib/coreapi/request.js

diff --git a/index.js b/index.js
index 252b110..530e453 100644
--- a/index.js
+++ b/index.js
@@ -4,8 +4,12 @@ process.chdir(__dirname);
 const fs = require('fs');
 fs.writeFileSync('pid.txt', process.pid);
 
+const matrix = require('komodo-sdk/matrix');
+matrix.NODE_ENV = process.env.NODE_ENV;
+
 const logger = require('komodo-sdk/logger');
 const coreUrl = require('komodo-sdk/core-url');
 logger.verbose('CORE URL: ' + coreUrl);
 
 require('./lib/http-listener');
+
diff --git a/lib/command-handler/error.js b/lib/command-handler/error.js
index a4952f4..d3a9e3d 100644
--- a/lib/command-handler/error.js
+++ b/lib/command-handler/error.js
@@ -6,4 +6,5 @@ exports.ERR_INVALID_FORMAT = 'Format perintah salah';
 exports.ERR_INVALID_CREDENTIAL = 'Kesalahan kredensial. User atau PIN tidak sesuai';
 exports.ERR_INVALID_CORE_RESPONSE = 'Respon CORE tidak valid';
 exports.ERR_INVALID_CORE_HTTP_STATUS_RESPONSE = 'CORE tidak merespon dengan HTTP status 200';
-exports.ERR_NOT_IMPLEMENTED = 'Perintah belum dapat diproses';
\ No newline at end of file
+exports.ERR_NOT_IMPLEMENTED = 'Perintah belum dapat diproses';
+exports.ERR_CORE_VERSION_NOT_SUFFICIENT = 'Versi CORE tidak mencukupi';
\ No newline at end of file
diff --git a/lib/coreapi/core-version.js b/lib/coreapi/core-version.js
new file mode 100644
index 0000000..931b54c
--- /dev/null
+++ b/lib/coreapi/core-version.js
@@ -0,0 +1,48 @@
+"use strict";
+
+const util = require('util');
+const naturalCompare = require('natural-compare-lite');
+
+const logger = require('komodo-sdk/logger');
+const matrix = require('komodo-sdk/matrix');
+
+const coreMatrixRequest =  util.promisify(require('./matrix'));
+const coreApiRequest = require('./request');
+
+const MINIMUM_VERSION = 'v1.33.1-3-g2ce5525';
+
+let _isSufficient = false;
+matrix.core_version_is_sufficient = false;
+matrix.core_version_requirement = MINIMUM_VERSION;
+
+function logIfDev(...args) {
+    matrix.NODE_ENV !== 'production' && logger.verbose(...args);
+}
+
+async function getCoreVersion() {
+    
+    logIfDev('CORE-VERSION: checking core version');
+
+    const coreMatrix = await coreMatrixRequest();
+    if (!coreMatrix || !coreMatrix.version_active) return;
+
+    _isSufficient = naturalCompare(MINIMUM_VERSION, coreMatrix.version_active) <= 0;
+    matrix.core_version_is_sufficient = _isSufficient;
+    logger.info('CORE-VERSION', {version_active: coreMatrix.version_active, minimum_version: MINIMUM_VERSION, sufficient: _isSufficient});
+
+    if (!_isSufficient) {
+        setTimeout(
+            function() {
+                getCoreVersion();
+            },
+            5000
+        )
+    }
+}
+getCoreVersion();
+
+function isSufficient() {
+    return _isSufficient;
+}
+
+module.exports = isSufficient();
\ No newline at end of file
diff --git a/lib/coreapi/index.js b/lib/coreapi/index.js
index fdd8ac4..32033f3 100644
--- a/lib/coreapi/index.js
+++ b/lib/coreapi/index.js
@@ -1,56 +1,19 @@
 "use strict";
 
-const request = require('request');
-
-const coreUrl = require('komodo-sdk/core-url');
+const matrix = require('komodo-sdk/matrix');
 const logger = require('komodo-sdk/logger');
+
 const commandError = require('../command-handler/error');
+const coreApiRequest = require('./request');
+require('./core-version');
 
-function execute(coreEndpoint, params, httpMethod, cb) {
-    const requestOptions = {
-        url: coreUrl + coreEndpoint,
-        method: httpMethod || 'GET'
-    }
 
-    if (requestOptions.method === 'GET') {
-        requestOptions.qs = params;
+function _coreApiRequest(...args) {
+    if (!matrix.core_version_is_sufficient) {
+        logger.info('Blocking request to CORE because of insufficient CORE version');
+        return;
     }
-    else if (requestOptions.method === 'POST') {
-        requestOptions.data = params;
-    }
-
-    logger.verbose('Requesting to core', {url: requestOptions.url, http_method: httpMethod, params: params});
-
-    request(requestOptions, function(err, res, body) {
-        const responseParams = {
-            directResponse: true,
-            httpStatusCode: res ? res.statusCode : null,
-            body: body
-        }
-
-        if (err) {
-            cb(commandError.ERR_INVALID_CORE_RESPONSE, null, responseParams);
-            return;
-        }
-
-        if (res.statusCode !== 200) {
-            cb(commandError.ERR_INVALID_CORE_HTTP_STATUS_RESPONSE, null, responseParams);
-            return;
-        }
-
-        try {
-            var coreResponseObject = JSON.parse(body);
-        }
-        catch(e) {
-            logger.verbose(commandError.ERR_INVALID_CORE_RESPONSE, {body: body})
-            cb(commandError.ERR_INVALID_CORE_RESPONSE, null, responseParams);
-            return;
-        }
-
-        
-        cb(err, coreResponseObject, responseParams);
-    })
-    
+    coreApiRequest(...args);
 }
 
-module.exports = execute;
\ No newline at end of file
+module.exports = _coreApiRequest;
\ No newline at end of file
diff --git a/lib/coreapi/matrix.js b/lib/coreapi/matrix.js
new file mode 100644
index 0000000..b5ad029
--- /dev/null
+++ b/lib/coreapi/matrix.js
@@ -0,0 +1,17 @@
+"use strict";
+
+const coreapiRequest = require('./request');
+
+function get(cb) {
+    coreapiRequest('/services/matrix', null, 'GET', function(err, responseObject, responseParams) {
+        if (err) {
+            cb(err);
+            return;
+        }
+
+        cb(null, responseObject);
+    });
+    
+}
+
+module.exports = get;
\ No newline at end of file
diff --git a/lib/coreapi/request.js b/lib/coreapi/request.js
new file mode 100644
index 0000000..15d4505
--- /dev/null
+++ b/lib/coreapi/request.js
@@ -0,0 +1,57 @@
+"use strict";
+
+const request = require('request');
+
+const coreUrl = require('komodo-sdk/core-url');
+const logger = require('komodo-sdk/logger');
+const commandError = require('../command-handler/error');
+
+function execute(coreEndpoint, params, httpMethod, cb) {
+
+    const requestOptions = {
+        url: coreUrl + coreEndpoint,
+        method: httpMethod || 'GET'
+    }
+
+    if (requestOptions.method === 'GET' && params) {
+        requestOptions.qs = params;
+    }
+    else if (requestOptions.method === 'POST' && params) {
+        requestOptions.data = params;
+    }
+
+    logger.verbose('Requesting to core', {url: requestOptions.url, http_method: httpMethod, params: params});
+
+    request(requestOptions, function(err, res, body) {
+        const responseParams = {
+            directResponse: true,
+            httpStatusCode: res ? res.statusCode : null,
+            body: body
+        }
+
+        if (err) {
+            cb(commandError.ERR_INVALID_CORE_RESPONSE, null, responseParams);
+            return;
+        }
+
+        if (res.statusCode !== 200) {
+            cb(commandError.ERR_INVALID_CORE_HTTP_STATUS_RESPONSE, null, responseParams);
+            return;
+        }
+
+        try {
+            var coreResponseObject = JSON.parse(body);
+        }
+        catch(e) {
+            logger.verbose(commandError.ERR_INVALID_CORE_RESPONSE, {body: body})
+            cb(commandError.ERR_INVALID_CORE_RESPONSE, null, responseParams);
+            return;
+        }
+
+        
+        cb(err, coreResponseObject, responseParams);
+    })
+    
+}
+
+module.exports = execute;
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index f8c5c6e..1871602 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2624,6 +2624,11 @@
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
+    "natural-compare-lite": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+      "integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q="
+    },
     "negotiator": {
       "version": "0.6.2",
       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
diff --git a/package.json b/package.json
index 1892683..f30ed0d 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
     "express": "^4.17.1",
     "express-ipfilter": "^1.0.1",
     "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git",
+    "natural-compare-lite": "^1.4.0",
     "request": "^2.88.0",
     "yargs": "^13.2.4"
   },
-- 
1.9.0