dl
Version:
DreamLab Libs
276 lines (238 loc) • 9.54 kB
JavaScript
var core = require('core');
var CredentialsProvider = core.credentials.CredentialsProvider;
var Event = core.event.Event;
var ErrorEvent = core.event.ErrorEvent;
var Loader = core.http.Loader;
var OpalRequest = require('./OpalRequest.js').OpalRequest;
var OpalLoader = require('./OpalLoader.js').OpalLoader;
var Types = core.common.Types;
var Sort = core.common.Sort;
var JsonRpcError = core.jsonrpc.JsonRpcError;
//Multiton placeholder
var instances = {};
var OpalCredentialsProvider = function (credentialId, identity, gtw) {
return OpalCredentialsProvider.getInstance(credentialId, identity, gtw);
};
/**
* Multition
* @static
*/
OpalCredentialsProvider.getInstance = function (credentialId, identity, gtw) {
/* ustawienei domyslnego identity */
if (!identity && process.env['OPAL_IDENTITY']) {
identity = process.env['OPAL_IDENTITY'];
}
if (!gtw) {
gtw = "default";
}
if (instances.hasOwnProperty(credentialId) && instances[credentialId].hasOwnProperty(identity) && instances[credentialId][identity]) {
return instances[credentialId][identity][gtw];
} else {
var obj = Object.create(OpalCredentialsProvider.prototype);
CredentialsProvider.call(obj);
obj._credentialId = credentialId;
obj._identity = identity;
obj._currentCredentials = null;
obj.refreshTime = OpalCredentialsProvider.DEFAULT_REFRESH_TIME;
obj.refreshTimeError = OpalCredentialsProvider.ERROR_REFRESH_TIME;
obj._retryCount = 0;
obj.request = new OpalRequest({
"url": "router.opaladmin.onetapi.pl",
"method": "get_credentials",
"params": {
"ds_alias": obj._credentialId
},
"application": obj._identity
});
if (gtw && gtw != "default") {
obj.request.setConnectionHost(gtw);
}
obj.loader = null;
obj._refreshInProgress = false;
obj._forceRefresh = false;
obj._permError = null;
obj._credentialsUpdatedTime = Date.now();
obj._lastRefreshTimer = null;
if (!instances[credentialId]) {
instances[credentialId] = {};
}
if (!instances[credentialId][identity]) {
instances[credentialId][identity] = {};
}
instances[credentialId][identity][gtw] = obj;
obj.refresh();
return obj;
}
};
OpalCredentialsProvider.prototype = Object.create(CredentialsProvider.prototype);
OpalCredentialsProvider.prototype.getCredentialId = function () {
return this._credentialId;
};
/**
* Returns copy of credentials object
*
* @returns {String}
*/
OpalCredentialsProvider.prototype._credentialsCopy = function () {
return JSON.parse(JSON.stringify(this._currentCredentials));
};
OpalCredentialsProvider.prototype.get = function (callback) {
if (this._currentCredentials && !this._refreshInProgress) {
callback(null, this._credentialsCopy());
} else if (this._permError) {
callback(CredentialsProvider.Event.ERROR, this._permError);
} else {
var that = this;
var onCredentials = function (e) {
that.removeEventListener(CredentialsProvider.Event.LOAD, onCredentials);
that.removeEventListener(CredentialsProvider.Event.TIMEOUT, onCredentialsTimeout);
callback(null, e.data);
};
var onCredentialsTimeout = function (e) {
if (this._currentCredentials) {
console.error(
"Credentials retrieving error / timeouted.",
"Credential key:", this._credentialId,
"Credentials identity:", this._identity,
"Returning old credentials:", this._currentCredentials
);
callback(CredentialsProvider.Event.TIMEOUT, this._credentialsCopy());
} else {
console.error(
"Credentials retrieving error / timeouted.",
"Credential key:", this._credentialId,
"Credentials identity:", this._identity,
"No credentials"
);
callback(CredentialsProvider.Event.ERROR, null);
}
that.removeEventListener(CredentialsProvider.Event.LOAD, onCredentials);
that.removeEventListener(CredentialsProvider.Event.TIMEOUT, onCredentialsTimeout);
}
this.addEventListener(CredentialsProvider.Event.LOAD, onCredentials, this);
this.addEventListener(CredentialsProvider.Event.TIMEOUT, onCredentialsTimeout, this);
if (!this._refreshInProgress) {
this.refresh();
}
}
};
OpalCredentialsProvider.prototype.refresh = function (force) {
force = typeof (force) == 'undefined' ? false : force;
if (!this._lastRefreshTimer) {
this._checkCredentialsRefresh();
}
this._forceRefresh = force;
this._refreshInProgress = true;
this._scheduleRefresh(0);
};
CredentialsProvider.prototype.destroy = function () {
if (this._refreshTimer) {
clearTimeout(this._refreshTimer);
}
if (this._lastRefreshTimer) {
clearTimeout(this._lastRefreshTimer);
}
this._retryCount = 0;
this._clearLoader();
delete instances[this._credentialId][this._identity];
};
OpalCredentialsProvider.prototype._handleRefresh = function () {
if (!this.loader) {
this.loader = new OpalLoader(this.request);
this.loader.addEventListener(OpalLoader.Event.JSON_RESPONSE, this._onLoad, this);
this.loader.addEventListener(OpalLoader.Event.HTTP_RESPONSE, this._onError, this);
this.loader.addEventListener(Loader.Event.ERROR, this._onError, this);
this.loader.load();
}
};
OpalCredentialsProvider.prototype._handleError = function (error) {
this._clearLoader();
console.error(
"Credentials retrieving error.",
"Credential key:", this._credentialId,
"Credentials identity:", this._identity,
"Error:", error
);
if (Types.isInstanceOf(error, JsonRpcError) && error.getCode() == OpalCredentialsProvider.OpalError.NOT_FOUND) {
this._permError = OpalCredentialsProvider.OpalError.NOT_FOUND;
}
this._retryCount++;
this._scheduleRefresh(this.refreshTimeError);
/* zwiększam timeout odpytywania od credentiale przy error */
this.refreshTimeError = Math.min(Math.floor(this.refreshTimeError * 1.1), OpalCredentialsProvider.DEFAULT_REFRESH_TIME);
this.dispatchEvent(new ErrorEvent(CredentialsProvider.Event.ERROR, error));
if (this._retryCount > 3) {
this.dispatchEvent(new Event(CredentialsProvider.Event.TIMEOUT, error));
}
};
OpalCredentialsProvider.prototype._onLoad = function (e) {
this._clearLoader();
this._refreshInProgress = false;
var rpc = e.data.getBody();
if (rpc.isError()) {
this._handleError(rpc.getError());
return;
}
this._permError = null;
this._retryCount = 0;
this.refreshTimeError = OpalCredentialsProvider.ERROR_REFRESH_TIME;
var newCredentials = Sort.keySort(rpc.getResult());
newCredentials.hosts = newCredentials.hosts.sort(function (a, b) {
var aStr = [a.host, a.port].join('_');
var bStr = [b.host, b.port].join('_');
if (aStr < bStr) {
return -1;
} else if (aStr > bStr) {
return 1;
}
return 0;
});
this._scheduleRefresh(this.refreshTime);
this._credentialsUpdatedTime = Date.now();
if (JSON.stringify(newCredentials) != JSON.stringify(this._currentCredentials) || this._forceRefresh) {
this._forceRefresh = false;
this._currentCredentials = newCredentials;
this.dispatchEvent(new Event(CredentialsProvider.Event.LOAD, this._credentialsCopy()));
}
};
OpalCredentialsProvider.prototype._onError = function (e) {
this._handleError(e.data);
};
OpalCredentialsProvider.prototype._clearLoader = function () {
if (this.loader) {
this.loader.removeEventListener(OpalLoader.Event.JSON_RESPONSE, this._onLoad);
this.loader.removeEventListener(OpalLoader.Event.HTTP_RESPONSE, this._onError);
this.loader.removeEventListener(Loader.Event.ERROR, this._onError);
this.loader = null;
}
};
OpalCredentialsProvider.prototype._scheduleRefresh = function (period) {
var that = this;
if (this._refreshTimer) {
clearTimeout(this._refreshTimer);
}
if (period === 0) {
that._refreshTimer = null;
that._handleRefresh();
} else {
this._refreshTimer = setTimeout(function () {
that._refreshTimer = null;
that._handleRefresh();
}, period);
}
};
OpalCredentialsProvider.prototype._checkCredentialsRefresh = function () {
var waitTime = OpalCredentialsProvider.DEFAULT_REFRESH_TIME * 2;
var diff = Date.now() - this._credentialsUpdatedTime;
if (diff > waitTime) {
console.error("OCP/Debug: Credentials haven't been loaded successfully for %s seconds |" + this._credentialId, diff / 1000);
}
this._lastRefreshTimer = setTimeout(this._checkCredentialsRefresh, OpalCredentialsProvider.DEFAULT_REFRESH_TIME);
};
OpalCredentialsProvider.Event = JSON.parse(JSON.stringify(CredentialsProvider.Event));
OpalCredentialsProvider.Error = JSON.parse(JSON.stringify(CredentialsProvider.Error));
OpalCredentialsProvider.DEFAULT_REFRESH_TIME = 60000;
OpalCredentialsProvider.ERROR_REFRESH_TIME = 500;
OpalCredentialsProvider.OpalError = {};
OpalCredentialsProvider.OpalError.NOT_FOUND = -31999;
exports.OpalCredentialsProvider = OpalCredentialsProvider;