Как получить список файлов из gcs?

После начала работы Google я использую следующий код, чтобы получить список всех файлов в удаленном каталоге

class GCSFileStorage {
    String bucket = "bucket_name";
    String remoteDirectoryPath = "remote/path";
    int fetchBlockSize = 1024 * 1024;
    GcsService gcsService =
      GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());

    List<String> list() {
        List<String> filenames = new List();
        ListResult listResult = gcsService.list(bucket, ListOptions.DEFAULT);
        while (listResult.hasNext()) {
            ListItem listItem = listResult.next();
            filenames += listItem.getName();
        }
        return filenames;
    }
}

GCSFileStorage gcs = new GCSFileStorage();
gcs.list();

Но этот код не выполняется с исключением:

java.io.IOException: com.google.appengine.tools.cloudstorage.RetriesExhaustedException:
...
Caused by: java.io.IOException: java.lang.NullPointerException
...
Caused by: java.lang.NullPointerException
    at com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService$BlobStorageAdapter.<init>(LocalRawGcsService.java:123)
    at com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService$BlobStorageAdapter.getInstance(LocalRawGcsService.java:184)

Я подозреваю, что я как-то должен авторизоваться в gcs, и это может быть причиной сбоя. Однако я не нашел подходящего способа инициировать все, что нужно gcs для работы.

2 ответа

Решение

Как упомянул @ozarov, клиент, которым я пользовался, специфичен для App Engine. Это было добавлено через зависимость

com.google.appengine.tools:appengine-gcs-client:0.5

Вместо этого следует использовать клиент REST API. Его зависимость

com.google.apis:google-api-services-storage:v1-rev44-1.20.0

Тогда код для получения списка файлов может выглядеть следующим образом

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.StorageScopes;
import com.google.api.services.storage.model.Objects;
import com.google.api.services.storage.model.StorageObject;
import com.google.common.collect.Lists;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.LinkedList;
import java.util.List;


class GCSFileStorage {
    String bucket = "bucket_name";
    String remoteDirectoryPath = "remote/path";
    Storage storage

    public GCSFileStorage() throws GeneralSecurityException, IOException {
        storage = setupStorage();
    }

    List<String> list() throws IOException {
        List<String> allItems = new LinkedList<String>();
        Objects response = storage.objects().list(bucket).
            setPrefix(remoteDirectoryPath).execute();
        for (StorageObject obj: response.getItems()) {
            allItems.add(obj.getName());
        }
        while (response.getNextPageToken() != null) {
            String pageToken = response.getNextPageToken();
            response = storage.objects().list(bucket).
                setPrefix(remoteDirectoryPath).setPageToken(pageToken).execute();
            for (StorageObject obj: response.getItems()) {
                allItems.add(obj.getName());
            }
        }
        return allItems;
    }


    Storage setupStorage() throws GeneralSecurityException, IOException {
        GoogleCredential credential = new GoogleCredential.Builder().
            setTransport(new NetHttpTransport()).
            setJsonFactory(new JacksonFactory()).
            setServiceAccountId("your_account_id").
            setServiceAccountScopes(
                Lists.newArrayList(StorageScopes.DEVSTORAGE_FULL_CONTROL)).
            setServiceAccountPrivateKeyFromP12File(
                new File("/local/path/to/private/key.p12")).
            build();

        return new Storage.
            Builder(new NetHttpTransport(),
                new JacksonFactory(), credential).
            setApplicationName("foo").build();
    }
}

Как вы запускаете этот код? Этот клиент GCS специфичен для App Engine и должен запускаться либо развернутым приложением, либо локально с использованием сервера приложений AE dev или модульных тестов (которые должны конфигурировать среду выполнения AE с использованием LocalServiceTestHelper).

Другие вопросы по тегам