Как установить заголовок HTTP в Apache JClouds?

Я использую Apache JClouds для подключения к своей установке Openstack Swift. Мне удалось загружать и скачивать объекты из Swift. Однако мне не удалось увидеть, как загрузить динамический большой объект в Swift.

Чтобы загрузить динамический большой объект, мне нужно сначала загрузить все сегменты, что я могу сделать как обычно. Затем мне нужно загрузить объект манифеста, чтобы логически объединить их. Проблема в том, чтобы сообщить Swift, что это объект манифеста, мне нужно установить специальный заголовок, который я не знаю, как это сделать с помощью API JClouds.

Вот пример динамического большого объекта с официального сайта openstack.

Код, который я использую:

public static void main(String[] args) throws IOException {
    BlobStore blobStore = ContextBuilder.newBuilder("swift").endpoint("http://localhost:8080/auth/v1.0")
            .credentials("test:test", "test").buildView(BlobStoreContext.class).getBlobStore();
    blobStore.createContainerInLocation(null, "container");

    ByteSource segment1 = ByteSource.wrap("foo".getBytes(Charsets.UTF_8));
    Blob seg1Blob = blobStore.blobBuilder("/foo/bar/1").payload(segment1).contentLength(segment1.size()).build();
    System.out.println(blobStore.putBlob("container", seg1Blob));

    ByteSource segment2 = ByteSource.wrap("bar".getBytes(Charsets.UTF_8));
    Blob seg2Blob = blobStore.blobBuilder("/foo/bar/2").payload(segment2).contentLength(segment2.size()).build();
    System.out.println(blobStore.putBlob("container", seg2Blob));

    ByteSource manifest = ByteSource.wrap("".getBytes(Charsets.UTF_8));
    // TODO: set manifest header here
    Blob manifestBlob = blobStore.blobBuilder("/foo/bar").payload(manifest).contentLength(manifest.size()).build();
    System.out.println(blobStore.putBlob("container", manifestBlob));

    Blob dloBlob = blobStore.getBlob("container", "/foo/bar");
    InputStream input = dloBlob.getPayload().openStream();
    while (true) {
        int i = input.read();
        if (i < 0) {
            break;
        }
        System.out.print((char) i); // should print "foobar"
    }
}

Часть "TODO" - моя проблема.


Отредактировано:

Мне указали, что Jclouds автоматически обрабатывает загрузку больших файлов, что не так полезно в нашем случае. На самом деле, мы не знаем, насколько большим будет файл или когда прибудет следующий сегмент, когда мы начинаем загружать первый сегмент. Наш API предназначен для того, чтобы клиент мог загружать свои файлы фрагментами выбранного им размера и в выбранное им время, а когда это было сделано, вызывать «коммит», чтобы сделать эти фрагменты файлом. Так что это заставляет нас захотеть загрузить манифест самостоятельно здесь.


person fengye87    schedule 04.04.2014    source источник


Ответы (3)


Согласно ответу @Everett Toews, мой код работает правильно:

public static void main(String[] args) throws IOException {
    CommonSwiftClient swift = ContextBuilder.newBuilder("swift").endpoint("http://localhost:8080/auth/v1.0")
            .credentials("test:test", "test").buildApi(CommonSwiftClient.class);

    SwiftObject segment1 = swift.newSwiftObject();
    segment1.getInfo().setName("foo/bar/1");
    segment1.setPayload("foo");
    swift.putObject("container", segment1);

    SwiftObject segment2 = swift.newSwiftObject();
    segment2.getInfo().setName("foo/bar/2");
    segment2.setPayload("bar");
    swift.putObject("container", segment2);

    swift.putObjectManifest("container", "foo/bar2");

    SwiftObject dlo = swift.getObject("container", "foo/bar", GetOptions.NONE);
    InputStream input = dlo.getPayload().openStream();
    while (true) {
        int i = input.read();
        if (i < 0) {
            break;
        }
        System.out.print((char) i);
    }
}
person fengye87    schedule 09.04.2014

jclouds пишет манифест за вас. Вот несколько примеров, которые могут вам помочь: UploadLargeObject и largeblob.MainApp.

person Everett Toews    schedule 04.04.2014
comment
Я заметил эти фрагменты, но они не очень полезны в нашем случае. См. отредактированный вопрос выше, извините за неясность в моем вопросе о происхождении. Но все равно спасибо, вы молодцы! - person fengye87; 08.04.2014

Попробуйте использовать

Map<String, String> manifestMetadata = ImmutableMap.of(
    "X-Object-Manifest", "<container>/<prefix>");
BlobBuilder.userMetadata(manifestMetadata)

Если это не сработает, вам, возможно, придется использовать CommonSwiftClient, как в CrossOriginResourceSharingContainer.java.

person Everett Toews    schedule 08.04.2014
comment
Пробовал пользовательские метаданные, но безуспешно, это ничего не влияет на заголовок http. Но CommonSwiftClient работает отлично, и ниже я разместил свой исправленный код. Большое спасибо! - person fengye87; 09.04.2014