2

Openstack Swift インストールに接続するために Apache JClouds を使用しています。Swift からオブジェクトをアップロードおよびダウンロードすることができました。ただし、動的なラージ オブジェクトを Swift にアップロードする方法がわかりませんでした。

動的ラージ オブジェクトをアップロードするには、最初にすべてのセグメントをアップロードする必要がありますが、これは通常どおり行うことができます。次に、マニフェスト オブジェクトをアップロードして、それらを論理的に結合する必要があります。問題は、これがマニフェスト オブジェクトであることを Swift に伝えることです。特別なヘッダーを設定する必要がありますが、JClouds API を使用してそれを行う方法がわかりません。

これは、openstack の公式 Web サイトからの動的ラージ オブジェクトの例です。

私が使用しているコード:

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 は、クライアントが自分の選択したサイズのチャンクで自分の選択した時間にファイルをアップロードできるように設計されており、完了したら「コミット」を呼び出してこれらのチャンクをファイルとして作成します。そのため、ここで独自にマニフェストをアップロードする必要があります。

4

3 に答える 3

2

@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);
    }
}
于 2014-04-09T02:29:53.463 に答える
1

jclouds がマニフェストの作成を処理します。UploadLargeObjectlargeblob.MainAppの例をいくつか紹介します。

于 2014-04-04T14:44:49.100 に答える
0

使ってみて

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

それがうまくいかない場合は、 CrossOriginResourceSharingContainer.java のようにCommonSwiftClientを使用する必要があるかもしれません。

于 2014-04-08T23:14:42.883 に答える