如何在 Apache JClouds 中设置 HTTP 标头?

Posted

技术标签:

【中文标题】如何在 Apache JClouds 中设置 HTTP 标头?【英文标题】:How to set HTTP header in Apache JClouds? 【发布时间】:2014-05-16 05:19:09 【问题描述】:

我正在使用 Apache JClouds 连接到我的 Openstack Swift 安装。我设法从 Swift 上传和下载对象。但是,我没有看到如何将动态大对象上传到 Swift。

要上传动态大对象,我需要先上传所有片段,我可以照常进行。然后我需要上传一个清单对象以逻辑组合它们。问题是告诉 Swift 这是一个清单对象,我需要设置一个特殊的标头,我不知道如何使用 JClouds api 来做到这一点。

这是来自openstack官网的动态大对象example。

我正在使用的代码:

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 旨在使客户端能够以自己选择的大小和自己选择的时间上传他们的文件,完成后,调用“提交”将这些块制作为文件。所以这让我们想在这里自己上传清单。

【问题讨论】:

【参考方案1】:

根据@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);
    

【讨论】:

【参考方案2】:

jclouds 会为您编写清单。以下是一些可能对您有所帮助的示例,UploadLargeObject 和 largeblob.MainApp。

【讨论】:

我注意到了这些 sn-ps,但在我们的案例中并不是很有帮助。请参阅上面编辑过的问题,很抱歉在我的起源问题中不清楚。不过谢谢你们,你们太棒了!【参考方案3】:

尝试使用

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

如果这不起作用,您可能必须使用 CrossOriginResourceSharingContainer.java 中的 CommonSwiftClient。

【讨论】:

尝试了用户元数据但没有运气,这对 http 标头没有任何影响。但是 CommonSwiftClient 工作得很好,我已经在下面发布了我的固定代码。非常感谢!

以上是关于如何在 Apache JClouds 中设置 HTTP 标头?的主要内容,如果未能解决你的问题,请参考以下文章

在 ssl VirtualHost 中设置 Apache mod_jk

如何使用 Apache jclouds 访问 HP Helion

如何在 Apache 2.4 cookie 中设置 unix 时间戳?

如何在 Apache FOP 中设置默认语言

如何在 apache xampp 中设置环境变量?

如何在 TEdit 控件中设置文本对齐