mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 12:49:06 +00:00
Send to zulip
This commit is contained in:
854
aws/lambda-nodejs18.x/UpdateZulipStreams/node_modules/aws-sdk/lib/service.js
generated
vendored
Normal file
854
aws/lambda-nodejs18.x/UpdateZulipStreams/node_modules/aws-sdk/lib/service.js
generated
vendored
Normal file
@@ -0,0 +1,854 @@
|
||||
var AWS = require('./core');
|
||||
var Api = require('./model/api');
|
||||
var regionConfig = require('./region_config');
|
||||
|
||||
var inherit = AWS.util.inherit;
|
||||
var clientCount = 0;
|
||||
var region_utils = require('./region/utils');
|
||||
|
||||
/**
|
||||
* The service class representing an AWS service.
|
||||
*
|
||||
* @class_abstract This class is an abstract class.
|
||||
*
|
||||
* @!attribute apiVersions
|
||||
* @return [Array<String>] the list of API versions supported by this service.
|
||||
* @readonly
|
||||
*/
|
||||
AWS.Service = inherit({
|
||||
/**
|
||||
* Create a new service object with a configuration object
|
||||
*
|
||||
* @param config [map] a map of configuration options
|
||||
*/
|
||||
constructor: function Service(config) {
|
||||
if (!this.loadServiceClass) {
|
||||
throw AWS.util.error(new Error(),
|
||||
'Service must be constructed with `new\' operator');
|
||||
}
|
||||
|
||||
if (config) {
|
||||
if (config.region) {
|
||||
var region = config.region;
|
||||
if (region_utils.isFipsRegion(region)) {
|
||||
config.region = region_utils.getRealRegion(region);
|
||||
config.useFipsEndpoint = true;
|
||||
}
|
||||
if (region_utils.isGlobalRegion(region)) {
|
||||
config.region = region_utils.getRealRegion(region);
|
||||
}
|
||||
}
|
||||
if (typeof config.useDualstack === 'boolean'
|
||||
&& typeof config.useDualstackEndpoint !== 'boolean') {
|
||||
config.useDualstackEndpoint = config.useDualstack;
|
||||
}
|
||||
}
|
||||
|
||||
var ServiceClass = this.loadServiceClass(config || {});
|
||||
if (ServiceClass) {
|
||||
var originalConfig = AWS.util.copy(config);
|
||||
var svc = new ServiceClass(config);
|
||||
Object.defineProperty(svc, '_originalConfig', {
|
||||
get: function() { return originalConfig; },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
svc._clientId = ++clientCount;
|
||||
return svc;
|
||||
}
|
||||
this.initialize(config);
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
initialize: function initialize(config) {
|
||||
var svcConfig = AWS.config[this.serviceIdentifier];
|
||||
this.config = new AWS.Config(AWS.config);
|
||||
if (svcConfig) this.config.update(svcConfig, true);
|
||||
if (config) this.config.update(config, true);
|
||||
|
||||
this.validateService();
|
||||
if (!this.config.endpoint) regionConfig.configureEndpoint(this);
|
||||
|
||||
this.config.endpoint = this.endpointFromTemplate(this.config.endpoint);
|
||||
this.setEndpoint(this.config.endpoint);
|
||||
//enable attaching listeners to service client
|
||||
AWS.SequentialExecutor.call(this);
|
||||
AWS.Service.addDefaultMonitoringListeners(this);
|
||||
if ((this.config.clientSideMonitoring || AWS.Service._clientSideMonitoring) && this.publisher) {
|
||||
var publisher = this.publisher;
|
||||
this.addNamedListener('PUBLISH_API_CALL', 'apiCall', function PUBLISH_API_CALL(event) {
|
||||
process.nextTick(function() {publisher.eventHandler(event);});
|
||||
});
|
||||
this.addNamedListener('PUBLISH_API_ATTEMPT', 'apiCallAttempt', function PUBLISH_API_ATTEMPT(event) {
|
||||
process.nextTick(function() {publisher.eventHandler(event);});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
validateService: function validateService() {
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
loadServiceClass: function loadServiceClass(serviceConfig) {
|
||||
var config = serviceConfig;
|
||||
if (!AWS.util.isEmpty(this.api)) {
|
||||
return null;
|
||||
} else if (config.apiConfig) {
|
||||
return AWS.Service.defineServiceApi(this.constructor, config.apiConfig);
|
||||
} else if (!this.constructor.services) {
|
||||
return null;
|
||||
} else {
|
||||
config = new AWS.Config(AWS.config);
|
||||
config.update(serviceConfig, true);
|
||||
var version = config.apiVersions[this.constructor.serviceIdentifier];
|
||||
version = version || config.apiVersion;
|
||||
return this.getLatestServiceClass(version);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
getLatestServiceClass: function getLatestServiceClass(version) {
|
||||
version = this.getLatestServiceVersion(version);
|
||||
if (this.constructor.services[version] === null) {
|
||||
AWS.Service.defineServiceApi(this.constructor, version);
|
||||
}
|
||||
|
||||
return this.constructor.services[version];
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
getLatestServiceVersion: function getLatestServiceVersion(version) {
|
||||
if (!this.constructor.services || this.constructor.services.length === 0) {
|
||||
throw new Error('No services defined on ' +
|
||||
this.constructor.serviceIdentifier);
|
||||
}
|
||||
|
||||
if (!version) {
|
||||
version = 'latest';
|
||||
} else if (AWS.util.isType(version, Date)) {
|
||||
version = AWS.util.date.iso8601(version).split('T')[0];
|
||||
}
|
||||
|
||||
if (Object.hasOwnProperty(this.constructor.services, version)) {
|
||||
return version;
|
||||
}
|
||||
|
||||
var keys = Object.keys(this.constructor.services).sort();
|
||||
var selectedVersion = null;
|
||||
for (var i = keys.length - 1; i >= 0; i--) {
|
||||
// versions that end in "*" are not available on disk and can be
|
||||
// skipped, so do not choose these as selectedVersions
|
||||
if (keys[i][keys[i].length - 1] !== '*') {
|
||||
selectedVersion = keys[i];
|
||||
}
|
||||
if (keys[i].substr(0, 10) <= version) {
|
||||
return selectedVersion;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Could not find ' + this.constructor.serviceIdentifier +
|
||||
' API to satisfy version constraint `' + version + '\'');
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
api: {},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
defaultRetryCount: 3,
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
customizeRequests: function customizeRequests(callback) {
|
||||
if (!callback) {
|
||||
this.customRequestHandler = null;
|
||||
} else if (typeof callback === 'function') {
|
||||
this.customRequestHandler = callback;
|
||||
} else {
|
||||
throw new Error('Invalid callback type \'' + typeof callback + '\' provided in customizeRequests');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls an operation on a service with the given input parameters.
|
||||
*
|
||||
* @param operation [String] the name of the operation to call on the service.
|
||||
* @param params [map] a map of input options for the operation
|
||||
* @callback callback function(err, data)
|
||||
* If a callback is supplied, it is called when a response is returned
|
||||
* from the service.
|
||||
* @param err [Error] the error object returned from the request.
|
||||
* Set to `null` if the request is successful.
|
||||
* @param data [Object] the de-serialized data returned from
|
||||
* the request. Set to `null` if a request error occurs.
|
||||
*/
|
||||
makeRequest: function makeRequest(operation, params, callback) {
|
||||
if (typeof params === 'function') {
|
||||
callback = params;
|
||||
params = null;
|
||||
}
|
||||
|
||||
params = params || {};
|
||||
if (this.config.params) { // copy only toplevel bound params
|
||||
var rules = this.api.operations[operation];
|
||||
if (rules) {
|
||||
params = AWS.util.copy(params);
|
||||
AWS.util.each(this.config.params, function(key, value) {
|
||||
if (rules.input.members[key]) {
|
||||
if (params[key] === undefined || params[key] === null) {
|
||||
params[key] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var request = new AWS.Request(this, operation, params);
|
||||
this.addAllRequestListeners(request);
|
||||
this.attachMonitoringEmitter(request);
|
||||
if (callback) request.send(callback);
|
||||
return request;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls an operation on a service with the given input parameters, without
|
||||
* any authentication data. This method is useful for "public" API operations.
|
||||
*
|
||||
* @param operation [String] the name of the operation to call on the service.
|
||||
* @param params [map] a map of input options for the operation
|
||||
* @callback callback function(err, data)
|
||||
* If a callback is supplied, it is called when a response is returned
|
||||
* from the service.
|
||||
* @param err [Error] the error object returned from the request.
|
||||
* Set to `null` if the request is successful.
|
||||
* @param data [Object] the de-serialized data returned from
|
||||
* the request. Set to `null` if a request error occurs.
|
||||
*/
|
||||
makeUnauthenticatedRequest: function makeUnauthenticatedRequest(operation, params, callback) {
|
||||
if (typeof params === 'function') {
|
||||
callback = params;
|
||||
params = {};
|
||||
}
|
||||
|
||||
var request = this.makeRequest(operation, params).toUnauthenticated();
|
||||
return callback ? request.send(callback) : request;
|
||||
},
|
||||
|
||||
/**
|
||||
* Waits for a given state
|
||||
*
|
||||
* @param state [String] the state on the service to wait for
|
||||
* @param params [map] a map of parameters to pass with each request
|
||||
* @option params $waiter [map] a map of configuration options for the waiter
|
||||
* @option params $waiter.delay [Number] The number of seconds to wait between
|
||||
* requests
|
||||
* @option params $waiter.maxAttempts [Number] The maximum number of requests
|
||||
* to send while waiting
|
||||
* @callback callback function(err, data)
|
||||
* If a callback is supplied, it is called when a response is returned
|
||||
* from the service.
|
||||
* @param err [Error] the error object returned from the request.
|
||||
* Set to `null` if the request is successful.
|
||||
* @param data [Object] the de-serialized data returned from
|
||||
* the request. Set to `null` if a request error occurs.
|
||||
*/
|
||||
waitFor: function waitFor(state, params, callback) {
|
||||
var waiter = new AWS.ResourceWaiter(this, state);
|
||||
return waiter.wait(params, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
addAllRequestListeners: function addAllRequestListeners(request) {
|
||||
var list = [AWS.events, AWS.EventListeners.Core, this.serviceInterface(),
|
||||
AWS.EventListeners.CorePost];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i]) request.addListeners(list[i]);
|
||||
}
|
||||
|
||||
// disable parameter validation
|
||||
if (!this.config.paramValidation) {
|
||||
request.removeListener('validate',
|
||||
AWS.EventListeners.Core.VALIDATE_PARAMETERS);
|
||||
}
|
||||
|
||||
if (this.config.logger) { // add logging events
|
||||
request.addListeners(AWS.EventListeners.Logger);
|
||||
}
|
||||
|
||||
this.setupRequestListeners(request);
|
||||
// call prototype's customRequestHandler
|
||||
if (typeof this.constructor.prototype.customRequestHandler === 'function') {
|
||||
this.constructor.prototype.customRequestHandler(request);
|
||||
}
|
||||
// call instance's customRequestHandler
|
||||
if (Object.prototype.hasOwnProperty.call(this, 'customRequestHandler') && typeof this.customRequestHandler === 'function') {
|
||||
this.customRequestHandler(request);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Event recording metrics for a whole API call.
|
||||
* @returns {object} a subset of api call metrics
|
||||
* @api private
|
||||
*/
|
||||
apiCallEvent: function apiCallEvent(request) {
|
||||
var api = request.service.api.operations[request.operation];
|
||||
var monitoringEvent = {
|
||||
Type: 'ApiCall',
|
||||
Api: api ? api.name : request.operation,
|
||||
Version: 1,
|
||||
Service: request.service.api.serviceId || request.service.api.endpointPrefix,
|
||||
Region: request.httpRequest.region,
|
||||
MaxRetriesExceeded: 0,
|
||||
UserAgent: request.httpRequest.getUserAgent(),
|
||||
};
|
||||
var response = request.response;
|
||||
if (response.httpResponse.statusCode) {
|
||||
monitoringEvent.FinalHttpStatusCode = response.httpResponse.statusCode;
|
||||
}
|
||||
if (response.error) {
|
||||
var error = response.error;
|
||||
var statusCode = response.httpResponse.statusCode;
|
||||
if (statusCode > 299) {
|
||||
if (error.code) monitoringEvent.FinalAwsException = error.code;
|
||||
if (error.message) monitoringEvent.FinalAwsExceptionMessage = error.message;
|
||||
} else {
|
||||
if (error.code || error.name) monitoringEvent.FinalSdkException = error.code || error.name;
|
||||
if (error.message) monitoringEvent.FinalSdkExceptionMessage = error.message;
|
||||
}
|
||||
}
|
||||
return monitoringEvent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Event recording metrics for an API call attempt.
|
||||
* @returns {object} a subset of api call attempt metrics
|
||||
* @api private
|
||||
*/
|
||||
apiAttemptEvent: function apiAttemptEvent(request) {
|
||||
var api = request.service.api.operations[request.operation];
|
||||
var monitoringEvent = {
|
||||
Type: 'ApiCallAttempt',
|
||||
Api: api ? api.name : request.operation,
|
||||
Version: 1,
|
||||
Service: request.service.api.serviceId || request.service.api.endpointPrefix,
|
||||
Fqdn: request.httpRequest.endpoint.hostname,
|
||||
UserAgent: request.httpRequest.getUserAgent(),
|
||||
};
|
||||
var response = request.response;
|
||||
if (response.httpResponse.statusCode) {
|
||||
monitoringEvent.HttpStatusCode = response.httpResponse.statusCode;
|
||||
}
|
||||
if (
|
||||
!request._unAuthenticated &&
|
||||
request.service.config.credentials &&
|
||||
request.service.config.credentials.accessKeyId
|
||||
) {
|
||||
monitoringEvent.AccessKey = request.service.config.credentials.accessKeyId;
|
||||
}
|
||||
if (!response.httpResponse.headers) return monitoringEvent;
|
||||
if (request.httpRequest.headers['x-amz-security-token']) {
|
||||
monitoringEvent.SessionToken = request.httpRequest.headers['x-amz-security-token'];
|
||||
}
|
||||
if (response.httpResponse.headers['x-amzn-requestid']) {
|
||||
monitoringEvent.XAmznRequestId = response.httpResponse.headers['x-amzn-requestid'];
|
||||
}
|
||||
if (response.httpResponse.headers['x-amz-request-id']) {
|
||||
monitoringEvent.XAmzRequestId = response.httpResponse.headers['x-amz-request-id'];
|
||||
}
|
||||
if (response.httpResponse.headers['x-amz-id-2']) {
|
||||
monitoringEvent.XAmzId2 = response.httpResponse.headers['x-amz-id-2'];
|
||||
}
|
||||
return monitoringEvent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add metrics of failed request.
|
||||
* @api private
|
||||
*/
|
||||
attemptFailEvent: function attemptFailEvent(request) {
|
||||
var monitoringEvent = this.apiAttemptEvent(request);
|
||||
var response = request.response;
|
||||
var error = response.error;
|
||||
if (response.httpResponse.statusCode > 299 ) {
|
||||
if (error.code) monitoringEvent.AwsException = error.code;
|
||||
if (error.message) monitoringEvent.AwsExceptionMessage = error.message;
|
||||
} else {
|
||||
if (error.code || error.name) monitoringEvent.SdkException = error.code || error.name;
|
||||
if (error.message) monitoringEvent.SdkExceptionMessage = error.message;
|
||||
}
|
||||
return monitoringEvent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach listeners to request object to fetch metrics of each request
|
||||
* and emit data object through \'ApiCall\' and \'ApiCallAttempt\' events.
|
||||
* @api private
|
||||
*/
|
||||
attachMonitoringEmitter: function attachMonitoringEmitter(request) {
|
||||
var attemptTimestamp; //timestamp marking the beginning of a request attempt
|
||||
var attemptStartRealTime; //Start time of request attempt. Used to calculating attemptLatency
|
||||
var attemptLatency; //latency from request sent out to http response reaching SDK
|
||||
var callStartRealTime; //Start time of API call. Used to calculating API call latency
|
||||
var attemptCount = 0; //request.retryCount is not reliable here
|
||||
var region; //region cache region for each attempt since it can be updated in plase (e.g. s3)
|
||||
var callTimestamp; //timestamp when the request is created
|
||||
var self = this;
|
||||
var addToHead = true;
|
||||
|
||||
request.on('validate', function () {
|
||||
callStartRealTime = AWS.util.realClock.now();
|
||||
callTimestamp = Date.now();
|
||||
}, addToHead);
|
||||
request.on('sign', function () {
|
||||
attemptStartRealTime = AWS.util.realClock.now();
|
||||
attemptTimestamp = Date.now();
|
||||
region = request.httpRequest.region;
|
||||
attemptCount++;
|
||||
}, addToHead);
|
||||
request.on('validateResponse', function() {
|
||||
attemptLatency = Math.round(AWS.util.realClock.now() - attemptStartRealTime);
|
||||
});
|
||||
request.addNamedListener('API_CALL_ATTEMPT', 'success', function API_CALL_ATTEMPT() {
|
||||
var apiAttemptEvent = self.apiAttemptEvent(request);
|
||||
apiAttemptEvent.Timestamp = attemptTimestamp;
|
||||
apiAttemptEvent.AttemptLatency = attemptLatency >= 0 ? attemptLatency : 0;
|
||||
apiAttemptEvent.Region = region;
|
||||
self.emit('apiCallAttempt', [apiAttemptEvent]);
|
||||
});
|
||||
request.addNamedListener('API_CALL_ATTEMPT_RETRY', 'retry', function API_CALL_ATTEMPT_RETRY() {
|
||||
var apiAttemptEvent = self.attemptFailEvent(request);
|
||||
apiAttemptEvent.Timestamp = attemptTimestamp;
|
||||
//attemptLatency may not be available if fail before response
|
||||
attemptLatency = attemptLatency ||
|
||||
Math.round(AWS.util.realClock.now() - attemptStartRealTime);
|
||||
apiAttemptEvent.AttemptLatency = attemptLatency >= 0 ? attemptLatency : 0;
|
||||
apiAttemptEvent.Region = region;
|
||||
self.emit('apiCallAttempt', [apiAttemptEvent]);
|
||||
});
|
||||
request.addNamedListener('API_CALL', 'complete', function API_CALL() {
|
||||
var apiCallEvent = self.apiCallEvent(request);
|
||||
apiCallEvent.AttemptCount = attemptCount;
|
||||
if (apiCallEvent.AttemptCount <= 0) return;
|
||||
apiCallEvent.Timestamp = callTimestamp;
|
||||
var latency = Math.round(AWS.util.realClock.now() - callStartRealTime);
|
||||
apiCallEvent.Latency = latency >= 0 ? latency : 0;
|
||||
var response = request.response;
|
||||
if (
|
||||
response.error &&
|
||||
response.error.retryable &&
|
||||
typeof response.retryCount === 'number' &&
|
||||
typeof response.maxRetries === 'number' &&
|
||||
(response.retryCount >= response.maxRetries)
|
||||
) {
|
||||
apiCallEvent.MaxRetriesExceeded = 1;
|
||||
}
|
||||
self.emit('apiCall', [apiCallEvent]);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Override this method to setup any custom request listeners for each
|
||||
* new request to the service.
|
||||
*
|
||||
* @method_abstract This is an abstract method.
|
||||
*/
|
||||
setupRequestListeners: function setupRequestListeners(request) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the signing name for a given request
|
||||
* @api private
|
||||
*/
|
||||
getSigningName: function getSigningName() {
|
||||
return this.api.signingName || this.api.endpointPrefix;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the signer class for a given request
|
||||
* @api private
|
||||
*/
|
||||
getSignerClass: function getSignerClass(request) {
|
||||
var version;
|
||||
// get operation authtype if present
|
||||
var operation = null;
|
||||
var authtype = '';
|
||||
if (request) {
|
||||
var operations = request.service.api.operations || {};
|
||||
operation = operations[request.operation] || null;
|
||||
authtype = operation ? operation.authtype : '';
|
||||
}
|
||||
if (this.config.signatureVersion) {
|
||||
version = this.config.signatureVersion;
|
||||
} else if (authtype === 'v4' || authtype === 'v4-unsigned-body') {
|
||||
version = 'v4';
|
||||
} else if (authtype === 'bearer') {
|
||||
version = 'bearer';
|
||||
} else {
|
||||
version = this.api.signatureVersion;
|
||||
}
|
||||
return AWS.Signers.RequestSigner.getVersion(version);
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
serviceInterface: function serviceInterface() {
|
||||
switch (this.api.protocol) {
|
||||
case 'ec2': return AWS.EventListeners.Query;
|
||||
case 'query': return AWS.EventListeners.Query;
|
||||
case 'json': return AWS.EventListeners.Json;
|
||||
case 'rest-json': return AWS.EventListeners.RestJson;
|
||||
case 'rest-xml': return AWS.EventListeners.RestXml;
|
||||
}
|
||||
if (this.api.protocol) {
|
||||
throw new Error('Invalid service `protocol\' ' +
|
||||
this.api.protocol + ' in API config');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
successfulResponse: function successfulResponse(resp) {
|
||||
return resp.httpResponse.statusCode < 300;
|
||||
},
|
||||
|
||||
/**
|
||||
* How many times a failed request should be retried before giving up.
|
||||
* the defaultRetryCount can be overriden by service classes.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
numRetries: function numRetries() {
|
||||
if (this.config.maxRetries !== undefined) {
|
||||
return this.config.maxRetries;
|
||||
} else {
|
||||
return this.defaultRetryCount;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
retryDelays: function retryDelays(retryCount, err) {
|
||||
return AWS.util.calculateRetryDelay(retryCount, this.config.retryDelayOptions, err);
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
retryableError: function retryableError(error) {
|
||||
if (this.timeoutError(error)) return true;
|
||||
if (this.networkingError(error)) return true;
|
||||
if (this.expiredCredentialsError(error)) return true;
|
||||
if (this.throttledError(error)) return true;
|
||||
if (error.statusCode >= 500) return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
networkingError: function networkingError(error) {
|
||||
return error.code === 'NetworkingError';
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
timeoutError: function timeoutError(error) {
|
||||
return error.code === 'TimeoutError';
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
expiredCredentialsError: function expiredCredentialsError(error) {
|
||||
// TODO : this only handles *one* of the expired credential codes
|
||||
return (error.code === 'ExpiredTokenException');
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
clockSkewError: function clockSkewError(error) {
|
||||
switch (error.code) {
|
||||
case 'RequestTimeTooSkewed':
|
||||
case 'RequestExpired':
|
||||
case 'InvalidSignatureException':
|
||||
case 'SignatureDoesNotMatch':
|
||||
case 'AuthFailure':
|
||||
case 'RequestInTheFuture':
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
getSkewCorrectedDate: function getSkewCorrectedDate() {
|
||||
return new Date(Date.now() + this.config.systemClockOffset);
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
applyClockOffset: function applyClockOffset(newServerTime) {
|
||||
if (newServerTime) {
|
||||
this.config.systemClockOffset = newServerTime - Date.now();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
isClockSkewed: function isClockSkewed(newServerTime) {
|
||||
if (newServerTime) {
|
||||
return Math.abs(this.getSkewCorrectedDate().getTime() - newServerTime) >= 300000;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
throttledError: function throttledError(error) {
|
||||
// this logic varies between services
|
||||
if (error.statusCode === 429) return true;
|
||||
switch (error.code) {
|
||||
case 'ProvisionedThroughputExceededException':
|
||||
case 'Throttling':
|
||||
case 'ThrottlingException':
|
||||
case 'RequestLimitExceeded':
|
||||
case 'RequestThrottled':
|
||||
case 'RequestThrottledException':
|
||||
case 'TooManyRequestsException':
|
||||
case 'TransactionInProgressException': //dynamodb
|
||||
case 'EC2ThrottledException':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
endpointFromTemplate: function endpointFromTemplate(endpoint) {
|
||||
if (typeof endpoint !== 'string') return endpoint;
|
||||
|
||||
var e = endpoint;
|
||||
e = e.replace(/\{service\}/g, this.api.endpointPrefix);
|
||||
e = e.replace(/\{region\}/g, this.config.region);
|
||||
e = e.replace(/\{scheme\}/g, this.config.sslEnabled ? 'https' : 'http');
|
||||
return e;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
setEndpoint: function setEndpoint(endpoint) {
|
||||
this.endpoint = new AWS.Endpoint(endpoint, this.config);
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
paginationConfig: function paginationConfig(operation, throwException) {
|
||||
var paginator = this.api.operations[operation].paginator;
|
||||
if (!paginator) {
|
||||
if (throwException) {
|
||||
var e = new Error();
|
||||
throw AWS.util.error(e, 'No pagination configuration for ' + operation);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return paginator;
|
||||
}
|
||||
});
|
||||
|
||||
AWS.util.update(AWS.Service, {
|
||||
|
||||
/**
|
||||
* Adds one method for each operation described in the api configuration
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
defineMethods: function defineMethods(svc) {
|
||||
AWS.util.each(svc.prototype.api.operations, function iterator(method) {
|
||||
if (svc.prototype[method]) return;
|
||||
var operation = svc.prototype.api.operations[method];
|
||||
if (operation.authtype === 'none') {
|
||||
svc.prototype[method] = function (params, callback) {
|
||||
return this.makeUnauthenticatedRequest(method, params, callback);
|
||||
};
|
||||
} else {
|
||||
svc.prototype[method] = function (params, callback) {
|
||||
return this.makeRequest(method, params, callback);
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a new Service class using a service identifier and list of versions
|
||||
* including an optional set of features (functions) to apply to the class
|
||||
* prototype.
|
||||
*
|
||||
* @param serviceIdentifier [String] the identifier for the service
|
||||
* @param versions [Array<String>] a list of versions that work with this
|
||||
* service
|
||||
* @param features [Object] an object to attach to the prototype
|
||||
* @return [Class<Service>] the service class defined by this function.
|
||||
*/
|
||||
defineService: function defineService(serviceIdentifier, versions, features) {
|
||||
AWS.Service._serviceMap[serviceIdentifier] = true;
|
||||
if (!Array.isArray(versions)) {
|
||||
features = versions;
|
||||
versions = [];
|
||||
}
|
||||
|
||||
var svc = inherit(AWS.Service, features || {});
|
||||
|
||||
if (typeof serviceIdentifier === 'string') {
|
||||
AWS.Service.addVersions(svc, versions);
|
||||
|
||||
var identifier = svc.serviceIdentifier || serviceIdentifier;
|
||||
svc.serviceIdentifier = identifier;
|
||||
} else { // defineService called with an API
|
||||
svc.prototype.api = serviceIdentifier;
|
||||
AWS.Service.defineMethods(svc);
|
||||
}
|
||||
AWS.SequentialExecutor.call(this.prototype);
|
||||
//util.clientSideMonitoring is only available in node
|
||||
if (!this.prototype.publisher && AWS.util.clientSideMonitoring) {
|
||||
var Publisher = AWS.util.clientSideMonitoring.Publisher;
|
||||
var configProvider = AWS.util.clientSideMonitoring.configProvider;
|
||||
var publisherConfig = configProvider();
|
||||
this.prototype.publisher = new Publisher(publisherConfig);
|
||||
if (publisherConfig.enabled) {
|
||||
//if csm is enabled in environment, SDK should send all metrics
|
||||
AWS.Service._clientSideMonitoring = true;
|
||||
}
|
||||
}
|
||||
AWS.SequentialExecutor.call(svc.prototype);
|
||||
AWS.Service.addDefaultMonitoringListeners(svc.prototype);
|
||||
return svc;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
addVersions: function addVersions(svc, versions) {
|
||||
if (!Array.isArray(versions)) versions = [versions];
|
||||
|
||||
svc.services = svc.services || {};
|
||||
for (var i = 0; i < versions.length; i++) {
|
||||
if (svc.services[versions[i]] === undefined) {
|
||||
svc.services[versions[i]] = null;
|
||||
}
|
||||
}
|
||||
|
||||
svc.apiVersions = Object.keys(svc.services).sort();
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
defineServiceApi: function defineServiceApi(superclass, version, apiConfig) {
|
||||
var svc = inherit(superclass, {
|
||||
serviceIdentifier: superclass.serviceIdentifier
|
||||
});
|
||||
|
||||
function setApi(api) {
|
||||
if (api.isApi) {
|
||||
svc.prototype.api = api;
|
||||
} else {
|
||||
svc.prototype.api = new Api(api, {
|
||||
serviceIdentifier: superclass.serviceIdentifier
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof version === 'string') {
|
||||
if (apiConfig) {
|
||||
setApi(apiConfig);
|
||||
} else {
|
||||
try {
|
||||
setApi(AWS.apiLoader(superclass.serviceIdentifier, version));
|
||||
} catch (err) {
|
||||
throw AWS.util.error(err, {
|
||||
message: 'Could not find API configuration ' +
|
||||
superclass.serviceIdentifier + '-' + version
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(superclass.services, version)) {
|
||||
superclass.apiVersions = superclass.apiVersions.concat(version).sort();
|
||||
}
|
||||
superclass.services[version] = svc;
|
||||
} else {
|
||||
setApi(version);
|
||||
}
|
||||
|
||||
AWS.Service.defineMethods(svc);
|
||||
return svc;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
hasService: function(identifier) {
|
||||
return Object.prototype.hasOwnProperty.call(AWS.Service._serviceMap, identifier);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param attachOn attach default monitoring listeners to object
|
||||
*
|
||||
* Each monitoring event should be emitted from service client to service constructor prototype and then
|
||||
* to global service prototype like bubbling up. These default monitoring events listener will transfer
|
||||
* the monitoring events to the upper layer.
|
||||
* @api private
|
||||
*/
|
||||
addDefaultMonitoringListeners: function addDefaultMonitoringListeners(attachOn) {
|
||||
attachOn.addNamedListener('MONITOR_EVENTS_BUBBLE', 'apiCallAttempt', function EVENTS_BUBBLE(event) {
|
||||
var baseClass = Object.getPrototypeOf(attachOn);
|
||||
if (baseClass._events) baseClass.emit('apiCallAttempt', [event]);
|
||||
});
|
||||
attachOn.addNamedListener('CALL_EVENTS_BUBBLE', 'apiCall', function CALL_EVENTS_BUBBLE(event) {
|
||||
var baseClass = Object.getPrototypeOf(attachOn);
|
||||
if (baseClass._events) baseClass.emit('apiCall', [event]);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
_serviceMap: {}
|
||||
});
|
||||
|
||||
AWS.util.mixin(AWS.Service, AWS.SequentialExecutor);
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
module.exports = AWS.Service;
|
||||
Reference in New Issue
Block a user