1515use GuzzleHttp \Promise \Create ;
1616use GuzzleHttp \Promise \RejectedPromise ;
1717use OCP \Files \StorageNotAvailableException ;
18+ use OCP \ICache ;
19+ use OCP \ICacheFactory ;
1820use OCP \ICertificateManager ;
1921use OCP \Server ;
2022use Psr \Log \LoggerInterface ;
@@ -28,6 +30,8 @@ trait S3ConnectionTrait {
2830
2931 protected ?S3Client $ connection = null ;
3032
33+ private ?ICache $ existingBucketsCache = null ;
34+
3135 protected function parseParams ($ params ) {
3236 if (empty ($ params ['bucket ' ])) {
3337 throw new \Exception ('Bucket has to be configured. ' );
@@ -82,6 +86,11 @@ public function getConnection() {
8286 return $ this ->connection ;
8387 }
8488
89+ if ($ this ->existingBucketsCache === null ) {
90+ $ this ->existingBucketsCache = Server::get (ICacheFactory::class)
91+ ->createLocal ('s3-bucket-exists-cache ' );
92+ }
93+
8594 $ scheme = (isset ($ this ->params ['use_ssl ' ]) && $ this ->params ['use_ssl ' ] === false ) ? 'http ' : 'https ' ;
8695 $ base_url = $ scheme . ':// ' . $ this ->params ['hostname ' ] . ': ' . $ this ->params ['port ' ] . '/ ' ;
8796
@@ -143,22 +152,30 @@ public function getConnection() {
143152 ['app ' => 'objectstore ' ]);
144153 }
145154
146- if ($ this ->params ['verify_bucket_exists ' ] && !$ this ->connection ->doesBucketExist ($ this ->bucket )) {
147- try {
148- $ logger ->info ('Bucket " ' . $ this ->bucket . '" does not exist - creating it. ' , ['app ' => 'objectstore ' ]);
149- if (!$ this ->connection ::isBucketDnsCompatible ($ this ->bucket )) {
150- throw new StorageNotAvailableException ('The bucket will not be created because the name is not dns compatible, please correct it: ' . $ this ->bucket );
151- }
152- $ this ->connection ->createBucket (['Bucket ' => $ this ->bucket ]);
153- $ this ->testTimeout ();
154- } catch (S3Exception $ e ) {
155- $ logger ->debug ('Invalid remote storage. ' , [
156- 'exception ' => $ e ,
157- 'app ' => 'objectstore ' ,
158- ]);
159- if ($ e ->getAwsErrorCode () !== 'BucketAlreadyOwnedByYou ' ) {
160- throw new StorageNotAvailableException ('Creation of bucket " ' . $ this ->bucket . '" failed. ' . $ e ->getMessage ());
155+ if ($ this ->params ['verify_bucket_exists ' ]) {
156+ $ cacheKey = $ this ->params ['hostname ' ] . $ this ->bucket ;
157+ $ exist = $ this ->existingBucketsCache ->get ($ cacheKey ) === 1 ;
158+
159+ if (!$ exist ) {
160+ if (!$ this ->connection ->doesBucketExist ($ this ->bucket )) {
161+ try {
162+ $ logger ->info ('Bucket " ' . $ this ->bucket . '" does not exist - creating it. ' , ['app ' => 'objectstore ' ]);
163+ if (!$ this ->connection ::isBucketDnsCompatible ($ this ->bucket )) {
164+ throw new StorageNotAvailableException ('The bucket will not be created because the name is not dns compatible, please correct it: ' . $ this ->bucket );
165+ }
166+ $ this ->connection ->createBucket (['Bucket ' => $ this ->bucket ]);
167+ $ this ->testTimeout ();
168+ } catch (S3Exception $ e ) {
169+ $ logger ->debug ('Invalid remote storage. ' , [
170+ 'exception ' => $ e ,
171+ 'app ' => 'objectstore ' ,
172+ ]);
173+ if ($ e ->getAwsErrorCode () !== 'BucketAlreadyOwnedByYou ' ) {
174+ throw new StorageNotAvailableException ('Creation of bucket " ' . $ this ->bucket . '" failed. ' . $ e ->getMessage ());
175+ }
176+ }
161177 }
178+ $ this ->existingBucketsCache ->set ($ cacheKey , 1 );
162179 }
163180 }
164181
0 commit comments