From 23f939ddf6683681141d1f2b5bdc46cd56c3d6b1 Mon Sep 17 00:00:00 2001 From: Jeremy Lindblom Date: Fri, 30 Aug 2013 16:57:56 -0700 Subject: [PATCH 1/5] [WIP] Refactoring config to support package-level configuration. --- src/Aws/Laravel/AwsServiceProvider.php | 19 +++-- src/config/config.php | 7 ++ .../Laravel/{Tests => Test}/AwsFacadeTest.php | 17 ++-- .../Laravel/Test/AwsServiceProviderTest.php | 65 +++++++++++++++ .../Test/AwsServiceProviderTestCase.php | 57 +++++++++++++ .../Laravel/Tests/AwsServiceProviderTest.php | 80 ------------------- tests/bootstrap.php | 1 + 7 files changed, 148 insertions(+), 98 deletions(-) create mode 100644 src/config/config.php rename tests/Aws/Laravel/{Tests => Test}/AwsFacadeTest.php (65%) create mode 100644 tests/Aws/Laravel/Test/AwsServiceProviderTest.php create mode 100644 tests/Aws/Laravel/Test/AwsServiceProviderTestCase.php delete mode 100644 tests/Aws/Laravel/Tests/AwsServiceProviderTest.php diff --git a/src/Aws/Laravel/AwsServiceProvider.php b/src/Aws/Laravel/AwsServiceProvider.php index 603d969..5f698e4 100644 --- a/src/Aws/Laravel/AwsServiceProvider.php +++ b/src/Aws/Laravel/AwsServiceProvider.php @@ -28,26 +28,30 @@ */ class AwsServiceProvider extends ServiceProvider { + const VERSION = '1.1.0'; + /** * @inheritdoc */ public function register() { $this->app['aws'] = $this->app->share(function ($app) { + // Retrieve the config + $config = $app['config']['aws'] ?: $app['config']['aws::config'] ?: array(); + if (isset($config['config_file'])) { + $config = $config['config_file']; + } + // Instantiate the AWS service builder - $config = !empty($app['config']['aws']) ? $app['config']['aws'] : array(); $aws = Aws::factory($config); - // Attach an event listener that will append the Laravel version number in the user agent string + // Attach an event listener that will append the Laravel and module version numbers to the user agent string $aws->getEventDispatcher()->addListener('service_builder.create_client', function (Event $event) { - // The version number is only available in BETA4+, so an extra check is needed - $version = defined('Illuminate\Foundation\Application::VERSION') ? Application::VERSION : '4.0.0'; - - // Add the listener to modify the UA string $clientConfig = $event['client']->getConfig(); $commandParams = $clientConfig->get(Client::COMMAND_PARAMS) ?: array(); + $userAgentSuffix = 'Laravel/' . Application::VERSION . ' L4MOD/' . AwsServiceProvider::VERSION; $clientConfig->set(Client::COMMAND_PARAMS, array_merge_recursive($commandParams, array( - UserAgentListener::OPTION => "Laravel/{$version}", + UserAgentListener::OPTION => $userAgentSuffix, ))); }); @@ -60,5 +64,6 @@ public function register() */ public function boot() { + $this->package('aws/aws-sdk-php-laravel', 'aws'); } } diff --git a/src/config/config.php b/src/config/config.php new file mode 100644 index 0000000..bc1e223 --- /dev/null +++ b/src/config/config.php @@ -0,0 +1,7 @@ + 'YOUR_AWS_ACCESS_KEY_ID', + 'secret' => 'YOUR_AWS_SECRET_KEY', + //'region' => 'YOUR_REGION', +); diff --git a/tests/Aws/Laravel/Tests/AwsFacadeTest.php b/tests/Aws/Laravel/Test/AwsFacadeTest.php similarity index 65% rename from tests/Aws/Laravel/Tests/AwsFacadeTest.php rename to tests/Aws/Laravel/Test/AwsFacadeTest.php index 3ee03a4..a117151 100644 --- a/tests/Aws/Laravel/Tests/AwsFacadeTest.php +++ b/tests/Aws/Laravel/Test/AwsFacadeTest.php @@ -14,29 +14,24 @@ * permissions and limitations under the License. */ -namespace Aws\Laravel\Tests; +namespace Aws\Laravel\Test; use Aws\Laravel\AwsFacade as AWS; -use Aws\Laravel\AwsServiceProvider; -use Illuminate\Foundation\Application; /** * AwsFacade test cases */ -class AwsFacadeTest extends \PHPUnit_Framework_TestCase +class AwsFacadeTest extends AwsServiceProviderTestCase { public function testFacadeCanBeResolvedToServiceInstance() { - // Setup the Laravel app and AWS service provider - $app = new Application(); - $app['config'] = array(); - $provider = new AwsServiceProvider($app); - $app->register($provider); - $provider->boot(); + $app = $this->setupApplication(); + $this->setupServiceProvider($app); + // Mount facades AWS::setFacadeApplication($app); - // Get an instance of a client (S3) to use for testing + // Get an instance of a client (S3) via its facade $s3 = AWS::get('s3'); $this->assertInstanceOf('Aws\S3\S3Client', $s3); } diff --git a/tests/Aws/Laravel/Test/AwsServiceProviderTest.php b/tests/Aws/Laravel/Test/AwsServiceProviderTest.php new file mode 100644 index 0000000..9707d4c --- /dev/null +++ b/tests/Aws/Laravel/Test/AwsServiceProviderTest.php @@ -0,0 +1,65 @@ +setupApplication(); + $this->setupServiceProvider($app); + + // Simulate global config + $app['config']->set('aws', array( + 'key' => 'FOO', + 'secret' => 'BAR', + )); + + // Get an instance of a client (S3) + /** @var $s3 \Aws\S3\S3Client */ + $s3 = $app['aws']->get('s3'); + $this->assertInstanceOf('Aws\S3\S3Client', $s3); + + // Verify that the client received the credentials from the global config + $this->assertEquals('FOO', $s3->getCredentials()->getAccessKeyId()); + $this->assertEquals('BAR', $s3->getCredentials()->getSecretKey()); + + // Make sure the user agent contains Laravel information + $command = $s3->getCommand('ListBuckets'); + $request = $command->prepare(); + $s3->dispatch('command.before_send', array('command' => $command)); + $this->assertRegExp('/.+Laravel\/.+L4MOD\/.+/', (string) $request->getHeader('User-Agent')); + } + + public function testRegisterAwsServiceProviderWithPackageConfig() + { + $app = $this->setupApplication(); + $this->setupServiceProvider($app); + + // Get an instance of a client (S3) + /** @var $s3 \Aws\S3\S3Client */ + $s3 = $app['aws']->get('s3'); + $this->assertInstanceOf('Aws\S3\S3Client', $s3); + + // Verify that the client received the credentials from the package config + $this->assertEquals('YOUR_AWS_ACCESS_KEY_ID', $s3->getCredentials()->getAccessKeyId()); + $this->assertEquals('YOUR_AWS_SECRET_KEY', $s3->getCredentials()->getSecretKey()); + } +} diff --git a/tests/Aws/Laravel/Test/AwsServiceProviderTestCase.php b/tests/Aws/Laravel/Test/AwsServiceProviderTestCase.php new file mode 100644 index 0000000..0467b8e --- /dev/null +++ b/tests/Aws/Laravel/Test/AwsServiceProviderTestCase.php @@ -0,0 +1,57 @@ +instance('path', 'foobar'); + $app->instance('files', new Filesystem); + $app->instance('config', new Repository($app->getConfigLoader(), 'foobar')); + + return $app; + } + + /** + * @param Application $app + * + * @return AwsServiceProvider + */ + protected function setupServiceProvider(Application $app) + { + // Create and register the provider + $provider = new AwsServiceProvider($app); + $app->register($provider); + $provider->boot(); + + return $provider; + } +} diff --git a/tests/Aws/Laravel/Tests/AwsServiceProviderTest.php b/tests/Aws/Laravel/Tests/AwsServiceProviderTest.php deleted file mode 100644 index 6f224a1..0000000 --- a/tests/Aws/Laravel/Tests/AwsServiceProviderTest.php +++ /dev/null @@ -1,80 +0,0 @@ -register($provider, array( - 'config' => array( - 'aws' => array( - 'key' => 'your-aws-access-key-id', - 'secret' => 'your-aws-secret-access-key', - ), - ), - )); - $provider->boot(); - - // Get an instance of a client (S3) to use for testing - /** @var $s3 \Aws\S3\S3Client */ - $s3 = $app['aws']->get('s3'); - $this->assertInstanceOf('Aws\S3\S3Client', $s3); - - // Verify that the app and clients created by the SDK receive the provided credentials - $this->assertEquals('your-aws-access-key-id', $app['config']['aws']['key']); - $this->assertEquals('your-aws-secret-access-key', $app['config']['aws']['secret']); - $this->assertEquals('your-aws-access-key-id', $s3->getCredentials()->getAccessKeyId()); - $this->assertEquals('your-aws-secret-access-key', $s3->getCredentials()->getSecretKey()); - - // Make sure the user agent contains "Laravel" - $command = $s3->getCommand('ListBuckets'); - $request = $command->prepare(); - $s3->dispatch('command.before_send', array('command' => $command)); - $this->assertRegExp('/.+Laravel\/.+/', (string) $request->getHeader('User-Agent')); - } - - /** - * @expectedException \Aws\Common\Exception\InstanceProfileCredentialsException - */ - public function testNoConfigProvided() - { - // Setup the Laravel app and AWS service provider - $app = new Application(); - $app['config'] = array(); - $provider = new AwsServiceProvider($app); - $app->register($provider); - $provider->boot(); - - // Make sure we can still get the S3Client - /** @var $s3 \Aws\S3\S3Client */ - $s3 = $app['aws']->get('s3'); - $this->assertInstanceOf('Aws\S3\S3Client', $s3); - - // Trigger the expected exception - $s3->getCredentials()->getAccessKeyId(); - } -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6c8c4f5..4f95ed7 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,3 +1,4 @@ Date: Fri, 30 Aug 2013 18:12:11 -0700 Subject: [PATCH 2/5] [WIP] Updated README and package config file. --- README.md | 79 +++++++++++++------------------------------ src/config/config.php | 48 +++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index ff87d70..a33fe7e 100644 --- a/README.md +++ b/README.md @@ -18,24 +18,28 @@ The AWS Service Provider can be installed via [Composer](http://getcomposer.org) } ``` -## Usage +## Configuration + +To use the AWS Service Provider, you must register the provider when bootstrapping your Laravel application. -To use the AWS Service Provider, you must register the provider when bootstrapping your Laravel application. There are -essentially two ways to do this. +Publish the package configuration using Artisan. -### 1. Use Laravel Configuration +```sh +php artisan config:publish aws/aws-sdk-php-laravel +``` -Create a new `app/config/aws.php` configuration file with the following options: +Update your settings in the generated `app/config/packages/aws/aws-sdk-php-laravel` configuration file. ```php return array( - 'key' => '', - 'secret' => '', - 'region' => Aws\Common\Enum\Region::US_WEST_2, + 'key' => 'YOUR_AWS_ACCESS_KEY_ID', + 'secret' => 'YOUR_AWS_SECRET_KEY', + 'region' => 'us-east-1', + 'config_file' => null, ); ``` -Find the `providers` key in `app/config/app.php` and register the AWS Service Provider. +Find the `providers` key in your `app/config/app.php` and register the AWS Service Provider. ```php 'providers' => array( @@ -44,7 +48,7 @@ Find the `providers` key in `app/config/app.php` and register the AWS Service Pr ) ``` -Find the `aliases` key in `app/config/app.php` and add the AWS facade alias. +Find the `aliases` key in your `app/config/app.php` and add the AWS facade alias. ```php 'aliases' => array( @@ -53,64 +57,29 @@ Find the `aliases` key in `app/config/app.php` and add the AWS facade alias. ) ``` -### 2. Manual Instantiation - -You can also register the provider and configuration options at runtime. This could be done in your global bootstrapping -process in `app/start/global.php`. - -```php -use Aws\Common\Enum\Region; -use Aws\Laravel\AwsServiceProvider; -use Illuminate\Foundation\Application; - -// Instantiate a new application. This is normally done by the Laravel framework and the instance is available in -// `app/start/global.php` for you to use. -$app = new Application; - -// Register the AWS service provider and provide your configuration -$app->register(new AwsServiceProvider($app), array( - 'config' => array( - 'aws' => array( - 'key' => '', - 'secret' => '', - 'region' => Region::US_WEST_2, - ), - ), -)); -``` - -You can alternatively specify the path to an AWS config file (see [AWS SDK for PHP](http://github.com/aws/aws-sdk-php) -for details about how to format this type of file). - -```php -$app->register(new AwsServiceProvider($app), array('config' => array('aws' => '/path/to/aws/config/file.php'))); -``` - -Either way, the value of `$app['config']['aws']` is passed directly into `Aws\Common\Aws::factory()`. - -### Retrieving and Using a Service Client +## Usage -In order to use the SDK from within your app, you need to retrieve it from the [Laravel IoC +In order to use the AWS SDK for PHP within your app, you need to retrieve it from the [Laravel IoC Container](http://four.laravel.com/docs/ioc). The following example uses the Amazon S3 client to upload a file. ```php $s3 = App::make('aws')->get('s3'); $s3->putObject(array( - 'Bucket' => '', - 'Key' => '', - 'SourceFile' => '/path/to/the/file/you/are/uploading.ext', + 'Bucket' => 'YOUR_BUCKET', + 'Key' => 'YOUR_OBJECT_KEY', + 'SourceFile' => '/the/path/to/the/file/you/are/uploading.ext', )); ``` -If the AWS Facade is registered within the `aliases` section of the application configuration, you can use -the following more expressive method. +If the AWS facade is registered within the `aliases` section of the application configuration, you can also use the +following technique. ```php $s3 = AWS::get('s3'); $s3->putObject(array( - 'Bucket' => '', - 'Key' => '', - 'SourceFile' => '/path/to/the/file/you/are/uploading.ext', + 'Bucket' => 'YOUR_BUCKET', + 'Key' => 'YOUR_OBJECT_KEY', + 'SourceFile' => '/the/path/to/the/file/you/are/uploading.ext', )); ``` diff --git a/src/config/config.php b/src/config/config.php index bc1e223..b728029 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -1,7 +1,53 @@ 'YOUR_AWS_ACCESS_KEY_ID', 'secret' => 'YOUR_AWS_SECRET_KEY', - //'region' => 'YOUR_REGION', + + /* + |-------------------------------------------------------------------------- + | AWS Region + |-------------------------------------------------------------------------- + | + | Many AWS services are available in multiple regions. You should specify + | the AWS region you would like to use, but please remember that not every + | service is available in every region. + | + | These are the regions: us-east-1, us-west-1, us-west-2, us-gov-west-1 + | eu-west-1, sa-east-1, ap-northeast-1, ap-southeast-1, ap-southeast-2 + | + */ + 'region' => 'us-east-1', + + /* + |-------------------------------------------------------------------------- + | AWS Config File Location + |-------------------------------------------------------------------------- + | + | Instead of specifying your credentials and region here, you can specify + | the location of an AWS SDK for PHP config file to use. These files provide + | more granular control over what credentials and regions you are using for + | each service. If you specify a filepath for this configuration setting, + | the others in this file will be ignored. See the SDK user guide for more + | information: http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/configuration.html#using-a-custom-configuration-file + | + */ + 'config_file' => null, + ); From 7c0e9ef2039733234107bf111a9b1711543a2385 Mon Sep 17 00:00:00 2001 From: Jeremy Lindblom Date: Fri, 30 Aug 2013 23:00:47 -0700 Subject: [PATCH 3/5] Added provides method and docblocks --- src/Aws/Laravel/AwsFacade.php | 2 +- src/Aws/Laravel/AwsServiceProvider.php | 18 ++++++++++++++++-- src/config/config.php | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/Aws/Laravel/AwsFacade.php b/src/Aws/Laravel/AwsFacade.php index 2a78b23..cf05f7d 100644 --- a/src/Aws/Laravel/AwsFacade.php +++ b/src/Aws/Laravel/AwsFacade.php @@ -19,7 +19,7 @@ use Illuminate\Support\Facades\Facade; /** - * AWS SDK for PHP service provider for Laravel applications + * Facade for the AWS service */ class AwsFacade extends Facade { diff --git a/src/Aws/Laravel/AwsServiceProvider.php b/src/Aws/Laravel/AwsServiceProvider.php index 5f698e4..c228846 100644 --- a/src/Aws/Laravel/AwsServiceProvider.php +++ b/src/Aws/Laravel/AwsServiceProvider.php @@ -31,7 +31,9 @@ class AwsServiceProvider extends ServiceProvider const VERSION = '1.1.0'; /** - * @inheritdoc + * Register the service provider. + * + * @return void */ public function register() { @@ -60,10 +62,22 @@ public function register() } /** - * @inheritdoc + * Bootstrap the application events. + * + * @return void */ public function boot() { $this->package('aws/aws-sdk-php-laravel', 'aws'); } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return array('aws'); + } } diff --git a/src/config/config.php b/src/config/config.php index b728029..2d89954 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -1,4 +1,18 @@ Date: Fri, 30 Aug 2013 23:55:25 -0700 Subject: [PATCH 4/5] Updated tests and configuration; 100% code coverage --- .gitignore | 1 - phpunit.xml | 27 +++++++++++++++++++ phpunit.xml.dist | 9 ------- .../Laravel/Test/AwsServiceProviderTest.php | 16 +++++++---- tests/Aws/Laravel/Test/test_services.json | 20 ++++++++++++++ tests/bootstrap.php | 8 ++++++ 6 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 phpunit.xml delete mode 100644 phpunit.xml.dist create mode 100644 tests/Aws/Laravel/Test/test_services.json diff --git a/.gitignore b/.gitignore index e285cad..b0def9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ composer.lock composer.phar -phpunit.xml vendor diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..4ec0310 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,27 @@ + + + + + + ./tests/ + + + + + + src + + vendor + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index 59a8649..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - ./tests - - - diff --git a/tests/Aws/Laravel/Test/AwsServiceProviderTest.php b/tests/Aws/Laravel/Test/AwsServiceProviderTest.php index 9707d4c..288325e 100644 --- a/tests/Aws/Laravel/Test/AwsServiceProviderTest.php +++ b/tests/Aws/Laravel/Test/AwsServiceProviderTest.php @@ -26,10 +26,9 @@ public function testRegisterAwsServiceProviderWithGlobalConfig() $app = $this->setupApplication(); $this->setupServiceProvider($app); - // Simulate global config + // Simulate global config; specify config file $app['config']->set('aws', array( - 'key' => 'FOO', - 'secret' => 'BAR', + 'config_file' => __DIR__ . '/test_services.json' )); // Get an instance of a client (S3) @@ -38,8 +37,8 @@ public function testRegisterAwsServiceProviderWithGlobalConfig() $this->assertInstanceOf('Aws\S3\S3Client', $s3); // Verify that the client received the credentials from the global config - $this->assertEquals('FOO', $s3->getCredentials()->getAccessKeyId()); - $this->assertEquals('BAR', $s3->getCredentials()->getSecretKey()); + $this->assertEquals('change_me', $s3->getCredentials()->getAccessKeyId()); + $this->assertEquals('change_me', $s3->getCredentials()->getSecretKey()); // Make sure the user agent contains Laravel information $command = $s3->getCommand('ListBuckets'); @@ -62,4 +61,11 @@ public function testRegisterAwsServiceProviderWithPackageConfig() $this->assertEquals('YOUR_AWS_ACCESS_KEY_ID', $s3->getCredentials()->getAccessKeyId()); $this->assertEquals('YOUR_AWS_SECRET_KEY', $s3->getCredentials()->getSecretKey()); } + + public function testServiceNameIsProvided() + { + $app = $this->setupApplication(); + $provider = $this->setupServiceProvider($app); + $this->assertContains('aws', $provider->provides()); + } } diff --git a/tests/Aws/Laravel/Test/test_services.json b/tests/Aws/Laravel/Test/test_services.json new file mode 100644 index 0000000..5a2778d --- /dev/null +++ b/tests/Aws/Laravel/Test/test_services.json @@ -0,0 +1,20 @@ +{ + "includes": ["_aws"], + "services": { + "default_settings": { + "params": { + "key": "change_me", + "secret": "change_me", + "region": "us-east-1", + "ssl.certificate_authority": true + } + }, + "cloudfront": { + "extends": "cloudfront", + "params": { + "private_key": "change_me", + "key_pair_id": "change_me" + } + } + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 4f95ed7..e9bc16e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,12 @@ Date: Tue, 3 Sep 2013 20:58:49 -0700 Subject: [PATCH 5/5] Removing an unneeded ternary statement --- src/Aws/Laravel/AwsServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aws/Laravel/AwsServiceProvider.php b/src/Aws/Laravel/AwsServiceProvider.php index c228846..d848114 100644 --- a/src/Aws/Laravel/AwsServiceProvider.php +++ b/src/Aws/Laravel/AwsServiceProvider.php @@ -39,7 +39,7 @@ public function register() { $this->app['aws'] = $this->app->share(function ($app) { // Retrieve the config - $config = $app['config']['aws'] ?: $app['config']['aws::config'] ?: array(); + $config = $app['config']['aws'] ?: $app['config']['aws::config']; if (isset($config['config_file'])) { $config = $config['config_file']; }