You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by zj...@apache.org on 2022/03/02 08:18:04 UTC

[zeppelin] branch master updated: [ZEPPELIN-5660] Implement move gcsnotebookrepo folder (#4298)

This is an automated email from the ASF dual-hosted git repository.

zjffdu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new 2b4b657  [ZEPPELIN-5660] Implement move gcsnotebookrepo folder (#4298)
2b4b657 is described below

commit 2b4b6570e1ceb921792b3a13973288a18076903d
Author: Bagus Nugroho Budi Nurtomo <Ba...@users.noreply.github.com>
AuthorDate: Wed Mar 2 15:17:56 2022 +0700

    [ZEPPELIN-5660] Implement move gcsnotebookrepo folder (#4298)
    
    * Implement Move and Remove folders for GCSNotebookRepo
    
    * Fix tests using wrong parameters
    
    * Small refactor
    
    * Updated tests
---
 .../zeppelin/notebook/repo/GCSNotebookRepo.java    | 58 ++++++++++++++++++++--
 .../notebook/repo/GCSNotebookRepoTest.java         | 43 +++++++++++++++-
 2 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/zeppelin-plugins/notebookrepo/gcs/src/main/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepo.java b/zeppelin-plugins/notebookrepo/gcs/src/main/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepo.java
index 0f2aed3..083f564 100644
--- a/zeppelin-plugins/notebookrepo/gcs/src/main/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepo.java
+++ b/zeppelin-plugins/notebookrepo/gcs/src/main/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepo.java
@@ -33,6 +33,7 @@ import com.google.gson.JsonParseException;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -214,8 +215,37 @@ public class GCSNotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public void move(String folderPath, String newFolderPath, AuthenticationInfo subject) {
+  public void move(String folderPath, String newFolderPath, AuthenticationInfo subject) throws IOException{
+    if(!folderPath.endsWith("/")) {
+      folderPath = folderPath + "/";
+    }
+    if(!newFolderPath.endsWith("/")) {
+      newFolderPath = newFolderPath + "/";
+    }
 
+    if(basePath.isPresent()) {
+      folderPath = basePath.get() + folderPath;
+      newFolderPath = basePath.get() + newFolderPath;
+    }
+    String oldPath = folderPath;
+    String newPath = newFolderPath;
+    try {
+      ArrayList<BlobId> toBeDeleted = new ArrayList();
+      storage.list(bucketName, Storage.BlobListOption.prefix(oldPath)).getValues()
+              .forEach((note -> {
+                toBeDeleted.add(note.getBlobId());
+              }));
+      if(toBeDeleted.isEmpty()) {
+        throw new IOException("Empty folder or folder does not exist: " + oldPath);
+      }
+      for(BlobId note: toBeDeleted) {
+        String newLocation = ("/" + note.getName()).replaceFirst(oldPath, newPath).substring(1);
+        storage.get(note).copyTo(bucketName, newLocation);
+        storage.delete(note);
+      };
+    } catch (Exception se) {
+      throw new IOException("Could not copy from " + oldPath + " to " + newPath + ": " + se.getMessage(), se);
+    }
   }
 
   @Override
@@ -233,8 +263,30 @@ public class GCSNotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public void remove(String folderPath, AuthenticationInfo subject) {
-
+  public void remove(String folderPath, AuthenticationInfo subject) throws IOException {
+    if(!folderPath.endsWith("/")) {
+      folderPath = folderPath + "/";
+    }
+    if(basePath.isPresent()) {
+      folderPath = basePath.get() + folderPath;
+    }
+    String oldPath = folderPath;
+    try {
+      ArrayList<BlobId> toBeDeleted = new ArrayList();
+      storage.list(bucketName, Storage.BlobListOption.prefix(oldPath)).getValues()
+              .forEach((note -> {
+                toBeDeleted.add(note.getBlobId());
+              }));
+      if(toBeDeleted.isEmpty()) {
+        throw new IOException("Empty folder or folder does not exist: " + oldPath);
+      }
+      // Note(Bagus): We an actually do this with storage.delete(toBeDeleted) but FakeStorageRPC used for tests still does not support it
+      for(BlobId note: toBeDeleted) {
+        storage.delete(note);
+      }
+    } catch (Exception se) {
+      throw new IOException("Could not delete from " + oldPath + ": " + se.getMessage(), se);
+    }
   }
 
   @Override
diff --git a/zeppelin-plugins/notebookrepo/gcs/src/test/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepoTest.java b/zeppelin-plugins/notebookrepo/gcs/src/test/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepoTest.java
index 69ef76f..86c6034 100644
--- a/zeppelin-plugins/notebookrepo/gcs/src/test/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepoTest.java
+++ b/zeppelin-plugins/notebookrepo/gcs/src/test/java/org/apache/zeppelin/notebook/repo/GCSNotebookRepoTest.java
@@ -187,8 +187,28 @@ public class GCSNotebookRepoTest {
     assertThat(storage.get(makeBlobId(runningNote.getId(), runningNote.getPath()))).isNull();
   }
 
+  @Test(expected = IOException.class)
+  public void testRemoveFolder_nonexistent() throws Exception {
+    notebookRepo.remove("id", "/name", AUTH_INFO);
+    fail();
+  }
+
+  @Test
+  public void testRemoveFolder() throws Exception {
+    Note firstNote = makeRunningNote();
+    firstNote.setPath("/folder/test_note");
+    create(firstNote);
+    Note secondNote = makeRunningNote();
+    secondNote.setPath("/folder/sub_folder/test_note_second");
+    create(secondNote);
+    notebookRepo.remove("/folder", AUTH_INFO);
+    assertThat(storage.get(makeBlobId(firstNote.getId(), firstNote.getPath()))).isNull();
+    assertThat(storage.get(makeBlobId(secondNote.getId(), secondNote.getPath()))).isNull();
+  }
+
+
   @Test
-  public void testMove_nonexistent() throws Exception {
+  public void testMove_nonexistent() {
     try {
       notebookRepo.move("id", "/name", "/name_new", AUTH_INFO);
       fail();
@@ -202,6 +222,27 @@ public class GCSNotebookRepoTest {
     assertThat(storage.get(makeBlobId(runningNote.getId(), runningNote.getPath()))).isNull();
   }
 
+  @Test(expected = IOException.class)
+  public void testMoveFolder_nonexistent() throws Exception {
+    notebookRepo.move("/name", "/name_new", AUTH_INFO);
+    fail();
+  }
+
+  @Test
+  public void testMoveFolder() throws Exception {
+    Note firstNote = makeRunningNote();
+    firstNote.setPath("/folder/test_note");
+    create(firstNote);
+    Note secondNote = makeRunningNote();
+    secondNote.setPath("/folder/sub_folder/test_note_second");
+    create(secondNote);
+    notebookRepo.move("/folder", "/folder_new", AUTH_INFO);
+    assertThat(storage.get(makeBlobId(firstNote.getId(), firstNote.getPath()))).isNull();
+    assertThat(storage.get(makeBlobId(firstNote.getId(), "/folder_new/test_note"))).isNotNull();
+    assertThat(storage.get(makeBlobId(secondNote.getId(), secondNote.getPath()))).isNull();
+    assertThat(storage.get(makeBlobId(secondNote.getId(), "/folder_new/sub_folder/test_note_second"))).isNotNull();
+  }
+
   private String makeName(String relativePath) {
     if (basePath.isPresent()) {
       return basePath.get() + "/" + relativePath;