gl-store-s3.js/node_modules/aws-sdk/lib/resource_waiter.js

205 lines
5.6 KiB
JavaScript

/**
* Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You
* may not use this file except in compliance with the License. A copy of
* the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
var AWS = require('./core');
var inherit = AWS.util.inherit;
var jmespath = require('jmespath');
/**
* @api private
*/
function CHECK_ACCEPTORS(resp) {
var waiter = resp.request._waiter;
var acceptors = waiter.config.acceptors;
var acceptorMatched = false;
var state = 'retry';
acceptors.forEach(function(acceptor) {
if (!acceptorMatched) {
var matcher = waiter.matchers[acceptor.matcher];
if (matcher && matcher(resp, acceptor.expected, acceptor.argument)) {
acceptorMatched = true;
state = acceptor.state;
}
}
});
if (!acceptorMatched && resp.error) state = 'failure';
if (state === 'success') {
waiter.setSuccess(resp);
} else {
waiter.setError(resp, state === 'retry');
}
}
/**
* @api private
*/
AWS.ResourceWaiter = inherit({
/**
* Waits for a given state on a service object
* @param service [Service] the service object to wait on
* @param state [String] the state (defined in waiter configuration) to wait
* for.
* @example Create a waiter for running EC2 instances
* var ec2 = new AWS.EC2;
* var waiter = new AWS.ResourceWaiter(ec2, 'instanceRunning');
*/
constructor: function constructor(service, state) {
this.service = service;
this.state = state;
this.loadWaiterConfig(this.state);
},
service: null,
state: null,
config: null,
matchers: {
path: function(resp, expected, argument) {
try {
var result = jmespath.search(resp.data, argument);
} catch (err) {
return false;
}
return jmespath.strictDeepEqual(result,expected);
},
pathAll: function(resp, expected, argument) {
try {
var results = jmespath.search(resp.data, argument);
} catch (err) {
return false;
}
if (!Array.isArray(results)) results = [results];
var numResults = results.length;
if (!numResults) return false;
for (var ind = 0 ; ind < numResults; ind++) {
if (!jmespath.strictDeepEqual(results[ind], expected)) {
return false;
}
}
return true;
},
pathAny: function(resp, expected, argument) {
try {
var results = jmespath.search(resp.data, argument);
} catch (err) {
return false;
}
if (!Array.isArray(results)) results = [results];
var numResults = results.length;
for (var ind = 0 ; ind < numResults; ind++) {
if (jmespath.strictDeepEqual(results[ind], expected)) {
return true;
}
}
return false;
},
status: function(resp, expected) {
var statusCode = resp.httpResponse.statusCode;
return (typeof statusCode === 'number') && (statusCode === expected);
},
error: function(resp, expected) {
if (typeof expected === 'string' && resp.error) {
return expected === resp.error.code;
}
// if expected is not string, can be boolean indicating presence of error
return expected === !!resp.error;
}
},
listeners: new AWS.SequentialExecutor().addNamedListeners(function(add) {
add('RETRY_CHECK', 'retry', function(resp) {
var waiter = resp.request._waiter;
if (resp.error && resp.error.code === 'ResourceNotReady') {
resp.error.retryDelay = (waiter.config.delay || 0) * 1000;
}
});
add('CHECK_OUTPUT', 'extractData', CHECK_ACCEPTORS);
add('CHECK_ERROR', 'extractError', CHECK_ACCEPTORS);
}),
/**
* @return [AWS.Request]
*/
wait: function wait(params, callback) {
if (typeof params === 'function') {
callback = params; params = undefined;
}
if (params && params.$waiter) {
params = AWS.util.copy(params);
if (typeof params.$waiter.delay === 'number') {
this.config.delay = params.$waiter.delay;
}
if (typeof params.$waiter.maxAttempts === 'number') {
this.config.maxAttempts = params.$waiter.maxAttempts;
}
delete params.$waiter;
}
var request = this.service.makeRequest(this.config.operation, params);
request._waiter = this;
request.response.maxRetries = this.config.maxAttempts;
request.addListeners(this.listeners);
if (callback) request.send(callback);
return request;
},
setSuccess: function setSuccess(resp) {
resp.error = null;
resp.data = resp.data || {};
resp.request.removeAllListeners('extractData');
},
setError: function setError(resp, retryable) {
resp.data = null;
resp.error = AWS.util.error(resp.error || new Error(), {
code: 'ResourceNotReady',
message: 'Resource is not in the state ' + this.state,
retryable: retryable
});
},
/**
* Loads waiter configuration from API configuration
*
* @api private
*/
loadWaiterConfig: function loadWaiterConfig(state) {
if (!this.service.api.waiters[state]) {
throw new AWS.util.error(new Error(), {
code: 'StateNotFoundError',
message: 'State ' + state + ' not found.'
});
}
this.config = AWS.util.copy(this.service.api.waiters[state]);
}
});