JCLOUDS-457: Added describeJob operation

Now Glacier client supports the describeJob operation.
This commit is contained in:
Roman C. Coedo 2014-06-25 22:04:36 +02:00 committed by Andrew Gaul
parent 59a43f8c2e
commit 7156947a18
6 changed files with 284 additions and 0 deletions

View File

@ -39,6 +39,7 @@ import org.jclouds.glacier.binders.BindHashesToHeaders;
import org.jclouds.glacier.binders.BindJobRequestToJsonPayload;
import org.jclouds.glacier.binders.BindMultipartTreeHashToHeaders;
import org.jclouds.glacier.binders.BindPartSizeToHeaders;
import org.jclouds.glacier.domain.JobMetadata;
import org.jclouds.glacier.domain.JobRequest;
import org.jclouds.glacier.domain.MultipartUploadMetadata;
import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection;
@ -48,6 +49,7 @@ import org.jclouds.glacier.fallbacks.FalseOnIllegalArgumentException;
import org.jclouds.glacier.filters.RequestAuthorizeSignature;
import org.jclouds.glacier.functions.ParseArchiveIdHeader;
import org.jclouds.glacier.functions.ParseJobIdHeader;
import org.jclouds.glacier.functions.ParseJobMetadataFromHttpContent;
import org.jclouds.glacier.functions.ParseMultipartUploadIdHeader;
import org.jclouds.glacier.functions.ParseMultipartUploadListFromHttpContent;
import org.jclouds.glacier.functions.ParseMultipartUploadPartListFromHttpContent;
@ -276,4 +278,16 @@ public interface GlacierAsyncClient extends Closeable {
ListenableFuture<String> initiateJob(
@ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName,
@BinderParam(BindJobRequestToJsonPayload.class) JobRequest job);
/**
* @see GlacierClient#describeJob
*/
@Named("DescribeJob")
@GET
@Path("/-/vaults/{vault}/jobs/{job}")
@ResponseParser(ParseJobMetadataFromHttpContent.class)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<JobMetadata> describeJob(
@ParamValidators(VaultNameValidator.class) @PathParam("vault") String vaultName,
@PathParam("job") String jobId);
}

View File

@ -20,6 +20,7 @@ import java.io.Closeable;
import java.net.URI;
import java.util.Map;
import org.jclouds.glacier.domain.JobMetadata;
import org.jclouds.glacier.domain.JobRequest;
import org.jclouds.glacier.domain.MultipartUploadMetadata;
import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection;
@ -231,4 +232,16 @@ public interface GlacierClient extends Closeable {
* @see <a href="http://docs.aws.amazon.com/amazonglacier/latest/dev/api-initiate-job-post.html" />
*/
String initiateJob(String vaultName, JobRequest job);
/**
* Describes a job.
*
* @param vaultName
* Name of the target Vault for the job.
* @param jobId
* Job identifier.
* @return The job metadata.
* @see <a href="http://docs.aws.amazon.com/amazonglacier/latest/dev/api-describe-job-get.html" />
*/
JobMetadata describeJob(String vaultName, String jobId);
}

View File

@ -0,0 +1,187 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.glacier.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import org.jclouds.glacier.util.ContentRange;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.gson.annotations.SerializedName;
public class JobMetadata {
@SerializedName("Action")
private final String action;
@SerializedName("ArchiveId")
private final String archiveId;
@SerializedName("ArchiveSizeInBytes")
private final Long archiveSizeInBytes;
@SerializedName("ArchiveSHA256TreeHash")
private final String archiveSHA256TreeHash;
@SerializedName("Completed")
private final boolean completed;
@SerializedName("CompletionDate")
private final Date completionDate;
@SerializedName("CreationDate")
private final Date creationDate;
@SerializedName("InventorySizeInBytes")
private final Long inventorySizeInBytes;
@SerializedName("JobDescription")
private final String jobDescription;
@SerializedName("JobId")
private final String jobId;
@SerializedName("RetrievalByteRange")
private final ContentRange retrievalByteRange;
@SerializedName("SHA256TreeHash")
private final String sha256TreeHash;
@SerializedName("SNSTopic")
private final String snsTopic;
@SerializedName("StatusCode")
private final String statusCode;
@SerializedName("StatusMessage")
private final String statusMessage;
@SerializedName("VaultARN")
private final String vaultArn;
@SerializedName("InventoryRetrievalParameters")
private final InventoryRetrievalParameters parameters;
@ConstructorProperties({ "Action", "ArchiveId", "ArchiveSizeInBytes", "ArchiveSHA256TreeHash", "Completed",
"CompletionDate", "CreationDate", "InventorySizeInBytes", "JobDescription", "JobId", "RetrievalByteRange",
"SHA256TreeHash", "SNSTopic", "StatusCode", "StatusMessage", "VaultARN", "InventoryRetrievalParameters" })
public JobMetadata(String action, @Nullable String archiveId, @Nullable Long archiveSizeInBytes,
@Nullable String archiveSHA256TreeHash, boolean completed, @Nullable Date completionDate, Date creationDate,
@Nullable Long inventorySizeInBytes, @Nullable String jobDescription, String jobId,
@Nullable String retrievalByteRange, @Nullable String sha256TreeHash, @Nullable String snsTopic,
String statusCode, String statusMessage, String vaultArn,
@Nullable InventoryRetrievalParameters parameters) {
super();
this.action = checkNotNull(action, "action");
this.archiveId = archiveId;
this.archiveSizeInBytes = archiveSizeInBytes;
this.archiveSHA256TreeHash = archiveSHA256TreeHash;
this.completed = checkNotNull(completed, "completed");
this.completionDate = completionDate == null ? null : (Date) completionDate.clone();
this.creationDate = (Date) checkNotNull(creationDate, "creationDate").clone();
this.inventorySizeInBytes = inventorySizeInBytes;
this.jobDescription = jobDescription;
this.jobId = checkNotNull(jobId, "jobId");
this.retrievalByteRange = retrievalByteRange == null ? null : ContentRange.fromString(retrievalByteRange);
this.sha256TreeHash = sha256TreeHash;
this.snsTopic = snsTopic;
this.statusCode = checkNotNull(statusCode, "statusCode");
this.statusMessage = checkNotNull(statusMessage, "statusMessage");
this.vaultArn = checkNotNull(vaultArn, "vaultArn");
this.parameters = parameters;
}
public String getAction() {
return action;
}
public String getArchiveId() {
return archiveId;
}
public Long getArchiveSizeInBytes() {
return archiveSizeInBytes;
}
public String getArchiveSHA256TreeHash() {
return archiveSHA256TreeHash;
}
public boolean isCompleted() {
return completed;
}
public Date getCompletionDate() {
return completionDate == null ? null : (Date) completionDate.clone();
}
public Date getCreationDate() {
return (Date) creationDate.clone();
}
public Long getInventorySizeInBytes() {
return inventorySizeInBytes;
}
public String getJobDescription() {
return jobDescription;
}
public String getJobId() {
return jobId;
}
public ContentRange getRetrievalByteRange() {
return retrievalByteRange;
}
public String getSha256TreeHash() {
return sha256TreeHash;
}
public String getSnsTopic() {
return snsTopic;
}
public String getStatusCode() {
return statusCode;
}
public String getStatusMessage() {
return statusMessage;
}
public String getVaultArn() {
return vaultArn;
}
public InventoryRetrievalParameters getParameters() {
return parameters;
}
@Override
public int hashCode() {
return Objects.hashCode(this.action, this.archiveId, this.archiveSizeInBytes, this.archiveSHA256TreeHash,
this.completed, this.completionDate, this.creationDate, this.inventorySizeInBytes, this.jobDescription,
this.jobId, this.retrievalByteRange, this.sha256TreeHash, this.snsTopic, this.statusCode,
this.statusMessage, this.vaultArn, this.parameters);
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
JobMetadata other = (JobMetadata) obj;
return Objects.equal(this.jobId, other.jobId);
}
@Override
public String toString() {
return "JobMetadata [jobId=" + jobId + ", statusCode=" + statusCode + ", statusMessage=" + statusMessage + "]";
}
}

View File

@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.glacier.functions;
import org.jclouds.glacier.domain.JobMetadata;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import com.google.inject.Inject;
import com.google.inject.TypeLiteral;
/**
* Parses the JSON job information from the HttpResponse.
*/
public class ParseJobMetadataFromHttpContent extends ParseJson<JobMetadata> {
@Inject
public ParseJobMetadataFromHttpContent(Json json) {
super(json, TypeLiteral.get(JobMetadata.class));
}
}

View File

@ -39,6 +39,7 @@ import org.jclouds.ContextBuilder;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.glacier.domain.ArchiveRetrievalJobRequest;
import org.jclouds.glacier.domain.InventoryRetrievalJobRequest;
import org.jclouds.glacier.domain.JobMetadata;
import org.jclouds.glacier.domain.MultipartUploadMetadata;
import org.jclouds.glacier.domain.PaginatedMultipartUploadCollection;
import org.jclouds.glacier.domain.PaginatedVaultCollection;
@ -437,4 +438,20 @@ public class GlacierClientMockTest {
assertEquals(job.getParameters().getEndDate(), endDate);
assertEquals(job.getType(), "inventory-retrieval");
}
@Test
public void testDescribeJob() throws IOException, InterruptedException {
MockResponse mr = buildBaseResponse(200);
mr.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8);
mr.setBody(getResponseBody("/json/describeJobResponseBody.json"));
mr.addHeader(HttpHeaders.CONTENT_LENGTH, mr.getBody().length);
server.enqueue(mr);
JobMetadata job = client.describeJob(VAULT_NAME, JOB_ID);
assertEquals(server.takeRequest().getRequestLine(), "GET /-/vaults/" + VAULT_NAME + "/jobs/" + JOB_ID + " " + HTTP);
assertEquals(job.getAction(), "ArchiveRetrieval");
assertEquals(job.getArchiveId(), ARCHIVE_ID);
assertEquals(ContentRange.fromString("0-16777215"), job.getRetrievalByteRange());
assertEquals(job.getVaultArn(), "arn:aws:glacier:us-east-1:012345678901:vaults/examplevault");
}
}

View File

@ -0,0 +1,18 @@
{
"Action": "ArchiveRetrieval",
"ArchiveId": "NkbByEejwEggmBz2fTHgJrg0XBoDfjP4q6iu87-TjhqG6eGoOY9Z8i1_AUyUsuhPAdTqLHy8pTl5nfCFJmDl2yEZONi5L26Omw12vcs01MNGntHEQL8MBfGlqrEXAMPLEArchiveId",
"ArchiveSizeInBytes": 16777216,
"ArchiveSHA256TreeHash": "beb0fe31a1c7ca8c6c04d574ea906e3f97b31fdca7571defb5b44dca89b5af60",
"Completed": false,
"CreationDate": "2012-05-15T17:21:39.339Z",
"CompletionDate": "2012-05-15T17:21:43.561Z",
"InventorySizeInBytes": null,
"JobDescription": "My ArchiveRetrieval Job",
"JobId": "HkF9p6o7yjhFx-K3CGl6fuSm6VzW9T7esGQfco8nUXVYwS0jlb5gq1JZ55yHgt5vP54ZShjoQzQVVh7vEXAMPLEjobID",
"RetrievalByteRange": "0-16777215",
"SHA256TreeHash": "beb0fe31a1c7ca8c6c04d574ea906e3f97b31fdca7571defb5b44dca89b5af60",
"SNSTopic": "arn:aws:sns:us-east-1:012345678901:mytopic",
"StatusCode": "InProgress",
"StatusMessage": "Operation in progress.",
"VaultARN": "arn:aws:glacier:us-east-1:012345678901:vaults/examplevault"
}