From 54f467fa7804a0a69e3d6cbe33f66f2194f6085f Mon Sep 17 00:00:00 2001 From: Adam Malone Date: Thu, 15 Oct 2020 19:04:29 +1100 Subject: [PATCH] Adds caching for uuid and environment. (#126) * Adds caching for uuid and environment. * Adds cache id, sets environment cache to 300, and prevents json_last_error from firing incorrectly. * Changes preg_split to explode for phpstan. * Makes composer discard changes before building the phar. * Removes inline environment variable. * Removes cache times on applications and environments. * Adds cache clear command. * Renames command files. --- composer.json | 3 +- composer.lock | 293 ++++++++++++++++++++++- src/Cli/CloudApi.php | 52 ++-- src/Commands/CacheClearCommand.php | 37 +++ tests/AcquiaCliTestCase.php | 3 + tests/Commands/CacheClearCommandTest.php | 30 +++ 6 files changed, 402 insertions(+), 16 deletions(-) create mode 100644 src/Commands/CacheClearCommand.php create mode 100644 tests/Commands/CacheClearCommandTest.php diff --git a/composer.json b/composer.json index 2f395f0..5bc200f 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "typhonius/acquia-logstream": "^0.0.7", "consolidation/robo": "^2", "symfony/lock": "^3|^4", - "symfony/yaml": "^3|^4" + "symfony/yaml": "^3|^4", + "symfony/cache": "^4|^5" }, "bin": ["bin/acquiacli"], "autoload":{ diff --git a/composer.lock b/composer.lock index 5599d72..cffd1fe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "db4662e623dcb6f4ee8b46d30355ed8e", + "content-hash": "387d8601bac37b934e38bb2990431d76", "packages": [ { "name": "consolidation/annotated-command", @@ -958,6 +958,52 @@ ], "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, { "name": "psr/container", "version": "1.0.0", @@ -1660,6 +1706,176 @@ ], "time": "2020-05-04T10:17:57+00:00" }, + { + "name": "symfony/cache", + "version": "v5.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "292cd57b7c2e3c37aa2f0a2fa42dacae567dd5cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/292cd57b7c2e3c37aa2f0a2fa42dacae567dd5cd", + "reference": "292cd57b7c2e3c37aa2f0a2fa42dacae567dd5cd", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "conflict": { + "doctrine/dbal": "<2.5", + "symfony/dependency-injection": "<4.4", + "symfony/http-kernel": "<4.4", + "symfony/var-dumper": "<4.4" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0", + "symfony/cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.5|^3.0", + "predis/predis": "^1.1", + "psr/simple-cache": "^1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-27T14:02:37+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/8034ca0b61d4dd967f3698aaa1da2507b631d0cb", + "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "^1.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" + }, { "name": "symfony/console", "version": "v4.4.15", @@ -2881,6 +3097,81 @@ ], "time": "2020-09-07T11:33:47+00:00" }, + { + "name": "symfony/var-exporter", + "version": "v5.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "8b858508e49beb257fd635104c3d449a8113e8fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8b858508e49beb257fd635104c3d449a8113e8fe", + "reference": "8b858508e49beb257fd635104c3d449a8113e8fe", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-08T14:19:54+00:00" + }, { "name": "symfony/yaml", "version": "v4.4.15", diff --git a/src/Cli/CloudApi.php b/src/Cli/CloudApi.php index 472c285..44cc4a7 100644 --- a/src/Cli/CloudApi.php +++ b/src/Cli/CloudApi.php @@ -11,6 +11,8 @@ use AcquiaCloudApi\Response\EnvironmentResponse; use AcquiaCloudApi\Response\OrganizationResponse; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Contracts\Cache\ItemInterface; /** * Class CloudApi @@ -56,15 +58,26 @@ public static function createClient(Config $config) */ public function getApplicationUuid($name) { - $app = new Applications($this->client); - $applications = $app->getAll(); + $cacheId = sprintf('application.%s', str_replace(':', '.', $name)); - foreach ($applications as $application) { - if ($name === $application->hosting->id) { - return $application->uuid; + $cache = new FilesystemAdapter('acquiacli'); + $cache->deleteItem($cacheId); + $return = $cache->get($cacheId, function (ItemInterface $item) { + $count = -1; + $name = str_replace('application:', '', str_replace('.', ':', $item->getKey())); + + $app = new Applications($this->client); + $applications = $app->getAll(); + + foreach ($applications as $application) { + if ($name === $application->hosting->id) { + return $application->uuid; + } } - } - throw new \Exception('Unable to find UUID for application'); + throw new \Exception('Unable to find UUID for application'); + }); + + return $return; } /** @@ -75,16 +88,27 @@ public function getApplicationUuid($name) */ public function getEnvironment($uuid, $environment) { - $environmentsAdapter = new Environments($this->client); - $environments = $environmentsAdapter->getAll($uuid); + $cacheId = sprintf('environment.%s.%s', $uuid, $environment); - foreach ($environments as $e) { - if ($environment === $e->name) { - return $e; + $cache = new FilesystemAdapter('acquiacli'); + $return = $cache->get($cacheId, function (ItemInterface $item) { + $split = explode('.', $item->getKey()); + $uuid = $split[1]; + $environment = $split[2]; + + $environmentsAdapter = new Environments($this->client); + $environments = $environmentsAdapter->getAll($uuid); + + foreach ($environments as $e) { + if ($environment === $e->name) { + return $e; + } } - } - throw new \Exception('Unable to find environment from environment name'); + throw new \Exception('Unable to find environment from environment name'); + }); + + return $return; } /** diff --git a/src/Commands/CacheClearCommand.php b/src/Commands/CacheClearCommand.php new file mode 100644 index 0000000..3f2d224 --- /dev/null +++ b/src/Commands/CacheClearCommand.php @@ -0,0 +1,37 @@ +clear()) { + return $this->say('AcquiaCli cache has been cleared'); + } + + throw new Exception('Problem clearing AcquiaCli cache.'); + } +} diff --git a/tests/AcquiaCliTestCase.php b/tests/AcquiaCliTestCase.php index e364db9..cad661d 100644 --- a/tests/AcquiaCliTestCase.php +++ b/tests/AcquiaCliTestCase.php @@ -32,6 +32,9 @@ public function setUp() protected function getPsr7StreamForFixture($fixture): StreamInterface { + // Clear json_last_error(). + json_decode('[]'); + $path = sprintf( '%s/vendor/typhonius/acquia-php-sdk-v2/tests/Fixtures/Endpoints/%s', dirname(__DIR__), diff --git a/tests/Commands/CacheClearCommandTest.php b/tests/Commands/CacheClearCommandTest.php new file mode 100644 index 0000000..30dd48f --- /dev/null +++ b/tests/Commands/CacheClearCommandTest.php @@ -0,0 +1,30 @@ +execute($command); + + // Ensure the items exist in the cache before we attempt a clear. + $cache = new FilesystemAdapter('acquiacli'); + + $this->assertTrue($cache->hasItem('application.devcloud.devcloud2')); + $this->assertTrue($cache->hasItem('environment.a47ac10b-58cc-4372-a567-0e02b2c3d470.dev')); + + // Clear the cache. + $command = ['cache:clear']; + $this->execute($command); + + $this->assertFalse($cache->hasItem('application.devcloud.devcloud2')); + $this->assertFalse($cache->hasItem('environment.a47ac10b-58cc-4372-a567-0e02b2c3d470.dev')); + } +}