Skip to content

Commit

Permalink
Making the step name part of the method for HandlerList
Browse files Browse the repository at this point in the history
This commit updates the HandlerList to include the step name as part of
adding a middleware to a handler. This adds methods for each step
prefixed with "append" or "prepend". I believe this to be a better API
as it does not require string parsing (e.g., "init:foo") and makes the
steps explicit and auto-completable.
  • Loading branch information
mtdowling committed May 13, 2015
1 parent b4fef8e commit 6c14894
Show file tree
Hide file tree
Showing 21 changed files with 220 additions and 208 deletions.
6 changes: 3 additions & 3 deletions src/AwsClient.php
Expand Up @@ -305,8 +305,7 @@ private function addSignatureMiddleware()
{
// Sign requests. This may need to be modified later to support
// variable signatures per/operation.
$this->handlerList->append(
'sign:signer',
$this->handlerList->appendSign(
Middleware::signer(
$this->credentialProvider,
constantly(SignatureProvider::resolve(
Expand All @@ -315,7 +314,8 @@ private function addSignatureMiddleware()
$this->api->getSigningName(),
$this->region
))
)
),
'signer'
);
}

Expand Down
10 changes: 5 additions & 5 deletions src/ClientResolver.php
Expand Up @@ -323,7 +323,7 @@ public static function _apply_retries($value, array &$args, HandlerList $list)
{
if ($value) {
$decider = RetryMiddleware::createDefaultDecider($value);
$list->append('sign:retry', Middleware::retry($decider));
$list->appendSign(Middleware::retry($decider), 'retry');
}
}

Expand Down Expand Up @@ -372,7 +372,7 @@ public static function _apply_api_provider(callable $value, array &$args, Handle
$args['serializer'] = Service::createSerializer($api, $args['endpoint']);
$args['parser'] = Service::createParser($api);
$args['error_parser'] = Service::createErrorParser($api->getProtocol());
$list->prepend('build:builder', Middleware::requestBuilder($args['serializer']));
$list->prependBuild(Middleware::requestBuilder($args['serializer']), 'builder');
}

public static function _apply_endpoint_provider(callable $value, array &$args)
Expand Down Expand Up @@ -408,9 +408,9 @@ public static function _apply_profile($_, array &$args)
public static function _apply_validate($value, array &$args, HandlerList $list)
{
if ($value === true) {
$list->append(
'init:validation',
Middleware::validation($args['api'], new Validator())
$list->appendValidate(
Middleware::validation($args['api'], new Validator()),
'validation'
);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/DynamoDb/DynamoDbClient.php
Expand Up @@ -46,16 +46,16 @@ public static function _applyRetryConfig($value, array &$args, HandlerList $list
return;
}

$list->append(
'sign:retry',
$list->appendSign(
Middleware::retry(
RetryMiddleware::createDefaultDecider($value),
function ($retries) {
return $retries
? (50 * (int) pow(2, $retries - 1)) / 1000
: 0;
}
)
),
'retry'
);
}

Expand Down
6 changes: 3 additions & 3 deletions src/Ec2/Ec2Client.php
Expand Up @@ -14,12 +14,12 @@ class Ec2Client extends AwsClient
public function __construct(array $args)
{
$args['with_resolved'] = function (array $args) {
$this->getHandlerList()->append(
'init:ec2.copy_snapshot',
$this->getHandlerList()->appendInit(
CopySnapshotMiddleware::wrap(
$this,
$args['endpoint_provider']
)
),
'ec2.copy_snapshot'
);
};

Expand Down
16 changes: 8 additions & 8 deletions src/Glacier/GlacierClient.php
Expand Up @@ -23,15 +23,15 @@ public function __construct(array $args)

// Setup middleware.
$stack = $this->getHandlerList();
$stack->append('build:glacier.api_version',$this->getApiVersionMiddleware());
$stack->append('build:glacier.checksum', $this->getChecksumsMiddleware());
$stack->append(
'build:glacier.content_type',
Middleware::contentType(['UploadArchive', 'UploadPart'])
$stack->appendBuild($this->getApiVersionMiddleware(), 'glacier.api_version');
$stack->appendBuild($this->getChecksumsMiddleware(), 'glacier.checksum');
$stack->appendBuild(
Middleware::contentType(['UploadArchive', 'UploadPart']),
'glacier.content_type'
);
$stack->append(
'init:glacier.source_file',
Middleware::sourceFile($this->getApi(), 'body', 'sourceFile')
$stack->appendInit(
Middleware::sourceFile($this->getApi(), 'body', 'sourceFile'),
'glacier.source_file'
);
}

Expand Down
144 changes: 97 additions & 47 deletions src/HandlerList.php
Expand Up @@ -7,11 +7,11 @@
* return a promise that is resolved with an AWS result object.
*
* The "front" of the list is invoked before the "end" of the list. You can add
* middleware to the front of the list using the "prepend" method, and the end
* of the list using the "append" method. The last function invoked in a
* handler list is the handler (a function that does not accept a next
* handler but rather is responsible for returning a promise that is fulfilled
* with an Aws\ResultInterface object).
* middleware to the front of the list using one of the "prepend" method, and
* the end of the list using one of the "append" method. The last function
* invoked in a handler list is the handler (a function that does not accept a
* next handler but rather is responsible for returning a promise that is
* fulfilled with an Aws\ResultInterface object).
*
* Handlers are ordered using a "step" that describes the step at which the
* SDK is when sending a command. The available steps are:
Expand All @@ -27,9 +27,7 @@
*
* Middleware can be registered with a name to allow you to easily add a
* middleware before or after another middleware by name. This also allows you
* to remove a middleware by name (in addition to removing by instance). You
* can provide a name for a middleware by specifying the step as "step:name"
* (e.g., "init:name").
* to remove a middleware by name (in addition to removing by instance).
*/
class HandlerList implements \Countable
{
Expand Down Expand Up @@ -116,51 +114,91 @@ public function hasHandler()
}

/**
* Append a middleware to the end of a step.
* Append a middleware to the init step.
*
* @param string $stepAndName Step to add the middleware to followed by
* an optional name, separated with ":"
* (e.g., "init:name").
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function append($stepAndName, callable $middleware)
public function appendInit(callable $middleware, $name = null)
{
list($step, $name) = $this->parseStepAndName($stepAndName);
$this->add(self::INIT, $name, $middleware);
}

if (!isset($this->steps[$step])) {
throw new \InvalidArgumentException("Invalid step: $step");
}
/**
* Prepend a middleware to the init step.
*
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function prependInit(callable $middleware, $name = null)
{
$this->add(self::INIT, $name, $middleware, true);
}

$this->sorted = null;
array_unshift($this->steps[$step], [$middleware, $name]);
/**
* Append a middleware to the validate step.
*
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function appendValidate(callable $middleware, $name = null)
{
$this->add(self::VALIDATE, $name, $middleware);
}

if ($name) {
$this->named[$name] = $step;
}
/**
* Prepend a middleware to the validate step.
*
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function prependValidate(callable $middleware, $name = null)
{
$this->add(self::VALIDATE, $name, $middleware, true);
}

/**
* Prepend a middleware to the beginning of a step.
* Append a middleware to the build step.
*
* @param string $stepAndName Step to add the middleware to followed by
* an optional name, separated with ":"
* (e.g., "init:name").
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function prepend($stepAndName, callable $middleware)
public function appendBuild(callable $middleware, $name = null)
{
list($step, $name) = $this->parseStepAndName($stepAndName);
$this->add(self::BUILD, $name, $middleware);
}

if (!isset($this->steps[$step])) {
throw new \InvalidArgumentException("Invalid step: $step");
}
/**
* Prepend a middleware to the build step.
*
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function prependBuild(callable $middleware, $name = null)
{
$this->add(self::BUILD, $name, $middleware, true);
}

$this->sorted = null;
$this->steps[$step][] = [$middleware, $name];
/**
* Append a middleware to the sign step.
*
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function appendSign(callable $middleware, $name = null)
{
$this->add(self::SIGN, $name, $middleware);
}

if ($name) {
$this->named[$name] = $step;
}
/**
* Prepend a middleware to the sign step.
*
* @param callable $middleware Middleware function to add.
* @param string $name Name of the middleware.
*/
public function prependSign(callable $middleware, $name = null)
{
$this->add(self::SIGN, $name, $middleware, true);
}

/**
Expand Down Expand Up @@ -251,17 +289,6 @@ public function count()
+ count($this->steps[self::SIGN]);
}

private function parseStepAndName($step)
{
$parts = explode(':', $step);

if (!isset($parts[1])) {
$parts[] = null;
}

return $parts;
}

/**
* Splices a function into the middleware list at a specific position.
*
Expand Down Expand Up @@ -371,4 +398,27 @@ private function removeByInstance(callable $fn)
}
}
}

/**
* Add a middleware to a step.
*
* @param string $step Middleware step.
* @param string $name Middleware name.
* @param callable $middleware Middleware function to add.
* @param bool $prepend Prepend instead of append.
*/
private function add($step, $name, callable $middleware, $prepend = false)
{
$this->sorted = null;

if ($prepend) {
$this->steps[$step][] = [$middleware, $name];
} else {
array_unshift($this->steps[$step], [$middleware, $name]);
}

if ($name) {
$this->named[$name] = $step;
}
}
}
2 changes: 1 addition & 1 deletion src/Multipart/AbstractUploader.php
Expand Up @@ -363,7 +363,7 @@ private function getUploadCommands($resultHandler)
$this->info['command']['upload'],
$data + $this->state->getId()
);
$command->getHandlerList()->append('sign:mup', $resultHandler);
$command->getHandlerList()->appendSign($resultHandler, 'mup');
yield $command;
if ($this->source->tell() > $partStartPos) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/Route53/Route53Client.php
Expand Up @@ -13,7 +13,7 @@ class Route53Client extends AwsClient
public function __construct(array $args)
{
parent::__construct($args);
$this->getHandlerList()->append('init:route53.clean_id', $this->cleanIdFn());
$this->getHandlerList()->appendInit($this->cleanIdFn(), 'route53.clean_id');
}

private function cleanIdFn()
Expand Down
24 changes: 12 additions & 12 deletions src/S3/S3Client.php
Expand Up @@ -122,11 +122,11 @@ public function __construct(array $args)

parent::__construct($args);
$stack = $this->getHandlerList();
$stack->append('init:s3.ssec', SSECMiddleware::wrap($this->getEndpoint()->getScheme()));
$stack->append('build:s3.md5', ApplyMd5Middleware::wrap($this->getConfig('calculate_md5')));
$stack->append(
'build:s3.content_type',
Middleware::contentType(['PutObject', 'UploadPart'])
$stack->appendInit(SSECMiddleware::wrap($this->getEndpoint()->getScheme()), 's3.ssec');
$stack->appendBuild(ApplyMd5Middleware::wrap($this->getConfig('calculate_md5')), 's3.md5');
$stack->appendBuild(
Middleware::contentType(['PutObject', 'UploadPart']),
's3.content_type'
);

// Use the bucket style middleware when using a "bucket_endpoint" or
Expand All @@ -136,15 +136,15 @@ public function __construct(array $args)
if ($bucketEndpoint
|| ($standard && !$this->getConfig('force_path_style'))
) {
$stack->append(
'build:s3.bucket_style',
BucketStyleMiddleware::wrap($bucketEndpoint)
$stack->appendBuild(
BucketStyleMiddleware::wrap($bucketEndpoint),
's3.bucket_style'
);
}

$stack->append('sign:s3.put_object_url', PutObjectUrlMiddleware::wrap());
$stack->append('sign:s3.permanent_redirect', PermanentRedirectMiddleware::wrap());
$stack->append('init:s3.source_file', Middleware::sourceFile($this->getApi()));
$stack->appendSign(PutObjectUrlMiddleware::wrap(), 's3.put_object_url');
$stack->appendSign(PermanentRedirectMiddleware::wrap(), 's3.permanent_redirect');
$stack->appendInit(Middleware::sourceFile($this->getApi()), 's3.source_file');
}

/**
Expand Down Expand Up @@ -512,7 +512,7 @@ public static function _applyRetryConfig($value, $_, HandlerList $list)
};

$delay = [RetryMiddleware::class, 'exponentialDelay'];
$list->append('sign:retry', Middleware::retry($decider, $delay));
$list->appendSign(Middleware::retry($decider, $delay), 'retry');
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Sqs/SqsClient.php
Expand Up @@ -16,8 +16,8 @@ public function __construct(array $config)
{
parent::__construct($config);
$list = $this->getHandlerList();
$list->append('build:sqs.queue_url', $this->queueUrl());
$list->append('sign:sqs.md5', $this->validateMd5());
$list->appendBuild($this->queueUrl(), 'sqs.queue_url');
$list->appendSign($this->validateMd5(), 'sqs.md5');
}

/**
Expand Down

0 comments on commit 6c14894

Please sign in to comment.