我在 Rackspace 的云文件中有几千个 blob,我需要为其更新内容类型。但是,我不知道如何使用 jclouds API 做到这一点。
如何更新现有 blob 上的元数据?
假设您已经为您的机架空间运行了整个设置,那么使用 jclouds 很容易:
首先使用以下详细信息进行初始化:
BlobStoreContext context = ContextBuilder.newBuilder(provider)
.credentials(username, apiKey)
.buildView(BlobStoreContext.class);
BlobStore blobStore = context.getBlobStore();
您现在可以构建一个新的 blob 以放入机架空间:
Blob blob = blobStore.blobBuilder(key) .userMetadata(metadata) .payload(value) .build();
blobStore.putBlob(container, blob);
value 是输入 bytes[] 并且 metadata 是与 blob 类似内容类型相关联的元数据的哈希映射。
如果你想做更新之类的操作:
RegionScopedBlobStoreContext context = ContextBuilder.newBuilder("openstack-swift")
.endpoint(config.getAuthUrl())
.credentials(config.getUser(), config.getPasswd())
.overrides(p)
.buildView(RegionScopedBlobStoreContext.class);
SwiftApi swift = (SwiftApi) ((org.jclouds.rest.internal.ApiContextImpl)context.unwrap()).getApi();
boolean success = swift.objectApiInRegionForContainer(config.getRegion(), container).updateMetadata(filename, metaData);
我知道这是一个概述,但我希望它能给你一个好的方向。
从 jclouds 2.1.0(和至少 1.9.3)开始,更改对象自定义元数据的 API 如下所示:
BlobStoreContext context = contextBuilder.buildView(BlobStoreContext.class);
SwiftApi api = (SwiftApi) ((org.jclouds.rest.internal.ApiContextImpl)context.unwrap()).getApi();
ObjectApi objectApi = api.getObjectApi(region, container);
Map<String, String> meta = new HashMap<>();
meta.put('some-meta', value);
objectApi.updateMetadata(blobName, meta);
无法通过这种方式更新内容类型,只能更新键开头为 from 的元数据X-Object-Meta-
。updateMetadata
自动为传递给它的所有键添加前缀X-Object-Meta-
. 在上面的示例中,带有键的自定义数据X-Object-Meta-some-meta
将被添加到 blob。
理论上updateRawMetadata
应该能够更新内容类型(它不会X-Object-Meta-
向键添加前缀并逐字传递它们)但是由于 jclouds 中的错误,它对于内容类型键失败并出现错误:
configuration error please use request.getPayload().getContentMetadata().setContentType(value) as opposed to adding a content type header
我已经通过 curl 检查了更新内容类型,它工作正常,所以这是 jclouds 中的一个错误:
curl -X POST -H "X-Auth-Token: $TOKEN" -H "Content-Type: $CONTENT_TYPE" "$PUBLIC_URL/$CONTAINER/$BLOB_NAME"
解决方法是使用copy
操作将 blob 复制到自身中,如API文档中所述:
您可以通过复制到同一个对象来使用 COPY 作为 POST 操作的替代方法
这可以使用与供应商/api 无关的 jclouds API 来完成,如下所示:
Blob blob = blobStore.getBlob(container, blobName);
MutableContentMetadata contentMetadata = blob.getPayload().getContentMetadata();
contentMetadata.setContentType(mimeType);
blobStore.copyBlob(getContainer, blobName, getContainer, blobName,
CopyOptions.builder().contentMetadata(contentMetadata).build());
或通过SwiftApi
(这不需要获取 blob 的元数据):
BlobStoreContext context = contextBuilder.buildView(BlobStoreContext.class);
SwiftApi api = (SwiftApi) ((org.jclouds.rest.internal.ApiContextImpl)context.unwrap()).getApi();
ObjectApi objectApi = api.getObjectApi(region, container);
Map<String, String> meta = new HashMap<>();
meta.put(HttpHeaders.CONTENT_TYPE, mimeType);
objectApi.copy(blobName, container, blobName, new HashMap<String, String>(), meta);