KiiHelper/KiiBase.js

/// <reference types='node' />
"use strict";
var Q = require("q");
var low = require("lowdb");
var request = require("request");
var _ = require("lodash");
var model_1 = require("../model");
var bulkUrl = 'http://121.199.7.69:9200/_bulk';
/**
 * KiiBase
 *
 * @export
 * @abstract
 * @class KiiBase
 */
var KiiBase = (function () {
    function KiiBase() {
        /**
         * db.json
         *
         * @protected
         * @type lowdb
         * @memberOf KiiBase
         */
        this.db = new low('./resource/db.json');
        /**
         * state cache
         *
         * @protected
         * @type lowdb
         * @memberOf KiiBase
         */
        this.cache = new low('./resource/stateCache.json');
        /**
         * request count
         *
         * @private
         * @type {number}
         * @memberOf KiiBase
         */
        this.counter = 0;
        /**
         * max request times
         *
         * @private
         * @type {number}
         * @memberOf KiiBase
         */
        this.maxRequest = 10;
        // gc mode
        if (global.gc)
            console.log('gc mode enables.');
        // init gateway
        this.gateway = new model_1.Gateway();
        // init cache file
        this.cache.defaults({ bulkAPI: bulkUrl, states: [] }).write();
        this.cacheState = this.cache.get('states');
    }
    /**
     * set kii app
     *
     * @param {any} _appID
     * @param {any} _appKey
     * @param {any} _site
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.setApp = function (_appID, _appKey, _site) {
        this.app = new model_1.App(_appID, _appKey, _site);
    };
    /**
     * set user
     *
     * @param {any} ownerToken
     * @param {any} ownerID
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.setUser = function (ownerToken, ownerID) {
        this.user = new model_1.User(ownerToken, ownerID);
    };
    /**
     * today date
     *
     * @returns {string}
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.today = function () {
        var today = new Date();
        var day = today.getDate();
        var month = today.getMonth() + 1;
        var year = today.getFullYear();
        return "" + year + month + day;
    };
    /**
     * onboard gateway by owner
     *
     * @abstract
     * @param {any} [properties]
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.onboardGatewayByOwner = function (properties) {
        var _this = this;
        var body = {
            'vendorThingID': this.gateway.vendorThingID,
            'thingPassword': this.gateway.password,
            'thingType': this.gateway.type,
            'owner': "USER:" + this.user.userID,
            'layoutPosition': 'GATEWAY'
        };
        if (properties)
            body['thingProperties'] = properties;
        var deferred = Q.defer();
        var options = {
            method: 'POST',
            url: this.app.site + "/thing-if/apps/" + this.app.appID + "/onboardings",
            headers: {
                authorization: "Bearer " + this.user.ownerToken,
                'content-type': 'application/vnd.kii.onboardingWithVendorThingIDByOwner+json',
                'Connection': 'keep-alive'
            },
            agentOptions: {
                ciphers: 'DES-CBC3-SHA'
            },
            body: JSON.stringify(body)
        };
        request(options, function (error, response, body) {
            _this.gcByCounter();
            if (error)
                deferred.reject(new Error(error));
            body = JSON.parse(body);
            _this.gateway.thingID = body.thingID;
            _this.gateway.accessToken = body.accessToken;
            _this.gateway.mqttEndpoint = body.mqttEndpoint;
            deferred.resolve(_this.gateway);
        });
        return deferred.promise;
    };
    /**
     * get all owned things from Kii by user
     *
     * @private
     * @returns Promise
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.getOwnedThings = function () {
        var _this = this;
        var deferred = Q.defer();
        var options = {
            method: 'POST',
            url: this.app.site + "/api/apps/" + this.app.appID + "/users/" + this.user.userID + "/buckets/OWNED_THINGS/query",
            headers: {
                Authorization: "Bearer " + this.user.ownerToken,
                'Content-Type': 'application/vnd.kii.QueryRequest+json',
                'Connection': 'keep-alive'
            },
            agentOptions: {
                ciphers: 'DES-CBC3-SHA'
            },
            body: JSON.stringify({
                'bucketQuery': {
                    'clause': {
                        'type': 'all'
                    }
                }
            })
        };
        request(options, function (error, response, body) {
            _this.gcByCounter();
            if (error)
                deferred.reject(new Error(error));
            _this.ownedThings = JSON.parse(body).results;
            deferred.resolve(_this.ownedThings);
        });
        return deferred.promise;
    };
    /**
     * cache states into cache.json
     *
     * @protected
     * @param {EndNodee} endnode
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.cacheStates = function (endnode) {
        var esnode = model_1.ESNode.parse(endnode);
        var record = this.cache.get('states').find({ thingID: endnode.thingID });
        if (record.value()) {
            record.get('cache').push(esnode).write();
        }
        else {
            this.cache.get('states').push({
                thingID: endnode.thingID,
                cache: [esnode]
            }).write();
        }
    };
    /**
     * upload lots of data to ES with bulk API
     *
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.bulkES = function () {
        var _this = this;
        try {
            if (!this.cacheState.size().value())
                return;
            if (!this.validateBulkTime())
                return;
            console.log('ES Bulk.');
            this.getOwnedThings().then(function () {
                var data = _this.traverseCacheState();
                return _this.callESBulkApi(data);
            }).then(function () {
                _this.cache.set('states', []).write();
            });
        }
        catch (err) {
            console.log('Bulk Error:', err);
        }
    };
    KiiBase.prototype.validateBulkTime = function () {
        if (this.lastBulk) {
            if (new Date().valueOf() > (this.lastBulk + 60000)) {
                this.lastBulk = new Date().valueOf();
                return true;
            }
            return false;
        }
        this.lastBulk = new Date().valueOf();
        return true;
    };
    /**
     * traverse each CacheState
     *
     * @private
     * @returns {string} es-formatted data
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.traverseCacheState = function () {
        var _this = this;
        var ret = '';
        this.cacheState.value().forEach(function (o) {
            var kiiThing = _this.getField(o.thingID);
            o.cache.forEach(function (esnode) {
                ret += _this.generateESFormat(esnode, kiiThing.fields);
            });
        });
        return ret;
    };
    /**
     * get the fields of the thing
     *
     * @private
     * @param {string} thingID
     * @returns {KiiThing}
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.getField = function (thingID) {
        return _.find(this.ownedThings, (function (o) { return o.thingID === thingID; }));
    };
    /**
     * generate ES well-formed data
     *
     * @private
     * @param {KiiThing} kiiThing
     * @param {*} fields
     * @returns
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.generateESFormat = function (esnode, fields) {
        var str = { create: { _index: this.app.appID, _type: 'states' } };
        esnode.fields = fields;
        return JSON.stringify(str) + "\n" + JSON.stringify(esnode) + "\n";
    };
    KiiBase.prototype.callESBulkApi = function (data) {
        var _this = this;
        var deferred = Q.defer();
        var options = {
            method: 'POST',
            url: this.cache.get('bulkAPI').value() || bulkUrl,
            headers: {
                Authorization: 'Bearer super_token',
                Connection: 'keep-alive'
            },
            body: data
        };
        request(options, function (error, response, body) {
            _this.gcByCounter();
            if (error)
                deferred.reject(new Error(error));
            deferred.resolve();
        });
        return deferred.promise;
    };
    /**
     * gc by count
     *
     * @protected
     * @returns
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.gcByCounter = function () {
        if (!global.gc)
            return;
        if (this.counter < this.maxRequest) {
            this.counter++;
        }
        else {
            this.counter = 0;
            global.gc();
        }
    };
    /**
     * gc by time
     *
     * @protected
     * @returns
     *
     * @memberOf KiiBase
     */
    KiiBase.prototype.gcByTime = function () {
        if (!global.gc)
            return;
        setInterval(function () {
            global.gc();
        }, 60000);
    };
    return KiiBase;
}());
exports.KiiBase = KiiBase;
//# sourceMappingURL=KiiBase.js.map