Răsfoiți Sursa

Use Bucket.deleteFiles to delete directory contents, instead of iterating

Simon Detheridge 6 ani în urmă
părinte
comite
eb93ae4b10

+ 10 - 22
services/filestore/app/js/GcsPersistor.js

@@ -191,41 +191,29 @@ async function deleteFile(bucketName, key) {
 }
 
 async function deleteDirectory(bucketName, key) {
-  let files
+  if (!key.match(/^[a-z0-9_-]+/i)) {
+    throw new NotFoundError({
+      message: 'deleteDirectoryKey is invalid or missing',
+      info: { bucketName, key }
+    })
+  }
 
   try {
-    const [response] = await storage
+    await storage
       .bucket(bucketName)
-      .getFiles({ directory: key })
-    files = response
+      .deleteFiles({ directory: key, force: true })
   } catch (err) {
     const error = PersistorHelper.wrapError(
       err,
-      'failed to list objects in GCS',
+      'failed to delete directory in GCS',
       { bucketName, key },
-      ReadError
+      WriteError
     )
     if (error instanceof NotFoundError) {
       return
     }
     throw error
   }
-
-  for (const index in files) {
-    try {
-      await files[index].delete()
-    } catch (err) {
-      const error = PersistorHelper.wrapError(
-        err,
-        'failed to delete object in GCS',
-        { bucketName, key },
-        WriteError
-      )
-      if (!(error instanceof NotFoundError)) {
-        throw error
-      }
-    }
-  }
 }
 
 async function directorySize(bucketName, key) {

+ 7 - 53
services/filestore/test/unit/js/GcsPersistorTests.js

@@ -84,7 +84,8 @@ describe('GcsPersistorTests', function() {
 
     GcsBucket = {
       file: sinon.stub().returns(GcsFile),
-      getFiles: sinon.stub().resolves([files])
+      getFiles: sinon.stub().resolves([files]),
+      deleteFiles: sinon.stub().resolves()
     }
 
     Storage = class {
@@ -516,67 +517,20 @@ describe('GcsPersistorTests', function() {
         return GcsPersistor.promises.deleteDirectory(bucket, key)
       })
 
-      it('should list the objects in the directory', function() {
+      it('should delete the objects in the directory', function() {
         expect(Storage.prototype.bucket).to.have.been.calledWith(bucket)
-        expect(GcsBucket.getFiles).to.have.been.calledWith({
-          directory: key
+        expect(GcsBucket.deleteFiles).to.have.been.calledWith({
+          directory: key,
+          force: true
         })
       })
-
-      it('should delete the objects', function() {
-        expect(files[0].delete).to.have.been.called
-        expect(files[1].delete).to.have.been.called
-      })
-    })
-
-    describe('when there are no files', function() {
-      beforeEach(async function() {
-        GcsBucket.getFiles.resolves([[]])
-        return GcsPersistor.promises.deleteDirectory(bucket, key)
-      })
-
-      it('should list the objects in the directory', function() {
-        expect(GcsBucket.getFiles).to.have.been.calledWith({
-          directory: key
-        })
-      })
-
-      it('should not try to delete any objects', function() {
-        expect(files[0].delete).not.to.have.been.called
-        expect(files[1].delete).not.to.have.been.called
-      })
-    })
-
-    describe('when there is an error listing the objects', function() {
-      let error
-
-      beforeEach(async function() {
-        GcsBucket.getFiles = sinon.stub().rejects(genericError)
-        try {
-          await GcsPersistor.promises.deleteDirectory(bucket, key)
-        } catch (err) {
-          error = err
-        }
-      })
-
-      it('should generate a ReadError', function() {
-        expect(error).to.be.an.instanceOf(Errors.ReadError)
-      })
-
-      it('should wrap the error', function() {
-        expect(error.cause).to.equal(genericError)
-      })
-
-      it('should not try to delete any objects', function() {
-        expect(files[0].delete).not.to.have.been.called
-      })
     })
 
     describe('when there is an error deleting the objects', function() {
       let error
 
       beforeEach(async function() {
-        files[0].delete = sinon.stub().rejects(genericError)
+        GcsBucket.deleteFiles = sinon.stub().rejects(genericError)
         try {
           await GcsPersistor.promises.deleteDirectory(bucket, key)
         } catch (err) {