Repository: jclouds-labs-aws Updated Branches: refs/heads/master 36e8cbda3 -> 3bc840e67
JCLOUDS-457: Add polling strategy The polling strategy interface for job operations and a simple implementation class have been added. This implementation waits an initial time and then polls at regular intervals. Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/commit/3bc840e6 Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/tree/3bc840e6 Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/diff/3bc840e6 Branch: refs/heads/master Commit: 3bc840e6794fa7cc5a62c5bc4632911ed44d45b0 Parents: 36e8cbd Author: Roman Coedo <[email protected]> Authored: Tue Jul 22 13:16:04 2014 +0200 Committer: Andrew Gaul <[email protected]> Committed: Fri Jul 25 23:18:42 2014 -0700 ---------------------------------------------------------------------- .../glacier/blobstore/GlacierBlobStore.java | 7 +- .../config/GlacierBlobStoreContextModule.java | 3 + .../blobstore/strategy/PollingStrategy.java | 21 ++++++ .../strategy/internal/BasePollingStrategy.java | 76 ++++++++++++++++++++ .../glacier/GlacierClientLongLiveTest.java | 12 ++-- 5 files changed, 110 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/3bc840e6/glacier/src/main/java/org/jclouds/glacier/blobstore/GlacierBlobStore.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/blobstore/GlacierBlobStore.java b/glacier/src/main/java/org/jclouds/glacier/blobstore/GlacierBlobStore.java index 15ebdc3..546abc1 100644 --- a/glacier/src/main/java/org/jclouds/glacier/blobstore/GlacierBlobStore.java +++ b/glacier/src/main/java/org/jclouds/glacier/blobstore/GlacierBlobStore.java @@ -37,6 +37,7 @@ import org.jclouds.domain.Location; import org.jclouds.glacier.GlacierClient; import org.jclouds.glacier.blobstore.functions.PaginatedVaultCollectionToStorageMetadata; import org.jclouds.glacier.blobstore.strategy.MultipartUploadStrategy; +import org.jclouds.glacier.blobstore.strategy.PollingStrategy; import org.jclouds.javax.annotation.Nullable; import com.google.common.base.Supplier; @@ -47,13 +48,17 @@ public class GlacierBlobStore extends BaseBlobStore { private final GlacierClient sync; private final Crypto crypto; private final Provider<MultipartUploadStrategy> multipartUploadStrategy; + private final Provider<PollingStrategy> pollingStrategy; private final PaginatedVaultCollectionToStorageMetadata vaultsToContainers; @Inject GlacierBlobStore(BlobStoreContext context, BlobUtils blobUtils, Supplier<Location> defaultLocation, @Memoized Supplier<Set<? extends Location>> locations, GlacierClient sync, Crypto crypto, - Provider<MultipartUploadStrategy> multipartUploadStrategy, PaginatedVaultCollectionToStorageMetadata vaultsToContainers) { + Provider<MultipartUploadStrategy> multipartUploadStrategy, + Provider<PollingStrategy> pollingStrategy, + PaginatedVaultCollectionToStorageMetadata vaultsToContainers) { super(context, blobUtils, defaultLocation, locations); + this.pollingStrategy = checkNotNull(pollingStrategy, "pollingStrategy"); this.vaultsToContainers = checkNotNull(vaultsToContainers, "vaultsToContainers"); this.multipartUploadStrategy = checkNotNull(multipartUploadStrategy, "multipartUploadStrategy"); this.sync = checkNotNull(sync, "sync"); http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/3bc840e6/glacier/src/main/java/org/jclouds/glacier/blobstore/config/GlacierBlobStoreContextModule.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/blobstore/config/GlacierBlobStoreContextModule.java b/glacier/src/main/java/org/jclouds/glacier/blobstore/config/GlacierBlobStoreContextModule.java index e330c53..e45c809 100644 --- a/glacier/src/main/java/org/jclouds/glacier/blobstore/config/GlacierBlobStoreContextModule.java +++ b/glacier/src/main/java/org/jclouds/glacier/blobstore/config/GlacierBlobStoreContextModule.java @@ -24,7 +24,9 @@ import org.jclouds.glacier.blobstore.GlacierAsyncBlobStore; import org.jclouds.glacier.blobstore.GlacierBlobStore; import org.jclouds.glacier.blobstore.strategy.ClearVaultStrategy; import org.jclouds.glacier.blobstore.strategy.MultipartUploadStrategy; +import org.jclouds.glacier.blobstore.strategy.PollingStrategy; import org.jclouds.glacier.blobstore.strategy.SlicingStrategy; +import org.jclouds.glacier.blobstore.strategy.internal.BasePollingStrategy; import org.jclouds.glacier.blobstore.strategy.internal.BaseSlicingStrategy; import org.jclouds.glacier.blobstore.strategy.internal.SequentialMultipartUploadStrategy; @@ -39,5 +41,6 @@ public class GlacierBlobStoreContextModule extends AbstractModule { bind(MultipartUploadStrategy.class).to(SequentialMultipartUploadStrategy.class); bind(SlicingStrategy.class).to(BaseSlicingStrategy.class); bind(ClearListStrategy.class).to(ClearVaultStrategy.class); + bind(PollingStrategy.class).to(BasePollingStrategy.class); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/3bc840e6/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/PollingStrategy.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/PollingStrategy.java b/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/PollingStrategy.java new file mode 100644 index 0000000..b208809 --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/PollingStrategy.java @@ -0,0 +1,21 @@ +/* + * 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.blobstore.strategy; + +public interface PollingStrategy { + boolean waitForSuccess(String vault, String job) throws InterruptedException; +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/3bc840e6/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/internal/BasePollingStrategy.java ---------------------------------------------------------------------- diff --git a/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/internal/BasePollingStrategy.java b/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/internal/BasePollingStrategy.java new file mode 100644 index 0000000..b9c90df --- /dev/null +++ b/glacier/src/main/java/org/jclouds/glacier/blobstore/strategy/internal/BasePollingStrategy.java @@ -0,0 +1,76 @@ +/* + * 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.blobstore.strategy.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.glacier.GlacierClient; +import org.jclouds.glacier.blobstore.strategy.PollingStrategy; +import org.jclouds.glacier.domain.JobMetadata; +import org.jclouds.glacier.domain.JobStatus; + +import com.google.inject.Inject; + +public class BasePollingStrategy implements PollingStrategy { + public static final long DEFAULT_INITIAL_WAIT = TimeUnit.HOURS.toMillis(3); + public static final long DEFAULT_TIME_BETWEEN_POLLS = TimeUnit.MINUTES.toMillis(15); + + private final GlacierClient client; + private final long initialWait; + private final long timeBetweenPolls; + + public BasePollingStrategy(long initialWait, long timeBetweenPolls, GlacierClient client) { + this.initialWait = initialWait; + this.timeBetweenPolls = timeBetweenPolls; + this.client = checkNotNull(client, "client"); + } + + @Inject + public BasePollingStrategy(GlacierClient client) { + this(DEFAULT_INITIAL_WAIT, DEFAULT_TIME_BETWEEN_POLLS, client); + } + + private boolean inProgress(String job, String vault) { + JobMetadata jobMetadata = client.describeJob(vault, job); + return (jobMetadata != null) && (jobMetadata.getStatusCode() == JobStatus.IN_PROGRESS); + } + + private void waitForJob(String job, String vault) throws InterruptedException { + Thread.sleep(initialWait); + while (inProgress(job, vault)) { + Thread.sleep(timeBetweenPolls); + } + } + + private boolean succeeded(String job, String vault) { + JobMetadata jobMetadata = client.describeJob(vault, job); + return (jobMetadata != null) && (jobMetadata.getStatusCode() == JobStatus.SUCCEEDED); + } + + @Override + public boolean waitForSuccess(String vault, String job) throws InterruptedException { + // Avoid waiting if the job doesn't exist + if (client.describeJob(vault, job) == null) { + return false; + } + waitForJob(job, vault); + return succeeded(job, vault); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/3bc840e6/glacier/src/test/java/org/jclouds/glacier/GlacierClientLongLiveTest.java ---------------------------------------------------------------------- diff --git a/glacier/src/test/java/org/jclouds/glacier/GlacierClientLongLiveTest.java b/glacier/src/test/java/org/jclouds/glacier/GlacierClientLongLiveTest.java index 1ab4939..ffe66f4 100644 --- a/glacier/src/test/java/org/jclouds/glacier/GlacierClientLongLiveTest.java +++ b/glacier/src/test/java/org/jclouds/glacier/GlacierClientLongLiveTest.java @@ -17,15 +17,16 @@ package org.jclouds.glacier; import static org.assertj.core.api.Assertions.assertThat; +import static org.jclouds.glacier.blobstore.strategy.internal.BasePollingStrategy.DEFAULT_TIME_BETWEEN_POLLS; import static org.jclouds.glacier.util.TestUtils.MiB; import static org.jclouds.glacier.util.TestUtils.buildData; import static org.jclouds.glacier.util.TestUtils.buildPayload; import java.io.IOException; import java.io.InputStream; -import java.util.concurrent.TimeUnit; import org.jclouds.apis.BaseApiLiveTest; +import org.jclouds.glacier.blobstore.strategy.internal.BasePollingStrategy; import org.jclouds.glacier.domain.ArchiveRetrievalJobRequest; import org.jclouds.glacier.domain.InventoryRetrievalJobRequest; import org.jclouds.glacier.domain.JobMetadata; @@ -44,8 +45,6 @@ import com.google.common.io.Closer; public class GlacierClientLongLiveTest extends BaseApiLiveTest<GlacierClient>{ private static final long PART_SIZE = 1; - private static final long INITIAL_WAIT = TimeUnit.HOURS.toMillis(3); - private static final long TIME_BETWEEN_POLLS = TimeUnit.MINUTES.toMillis(15); private static final String VAULT_NAME = "JCLOUDS_LIVE_TESTS"; private static final String ARCHIVE_DESCRIPTION = "test archive"; @@ -112,11 +111,8 @@ public class GlacierClientLongLiveTest extends BaseApiLiveTest<GlacierClient>{ @Test(groups = {"live", "livelong", "longtest"}, dependsOnMethods = {"testInitiateJob", "testDescribeJob", "testListJobs"}) public void testWaitForSucceed() throws InterruptedException { - Thread.sleep(INITIAL_WAIT); - while (api.describeJob(VAULT_NAME, archiveRetrievalJob).getStatusCode() == JobStatus.IN_PROGRESS || - api.describeJob(VAULT_NAME, inventoryRetrievalJob).getStatusCode() == JobStatus.IN_PROGRESS) { - Thread.sleep(TIME_BETWEEN_POLLS); - } + new BasePollingStrategy(api).waitForSuccess(VAULT_NAME, archiveRetrievalJob); + new BasePollingStrategy(0, DEFAULT_TIME_BETWEEN_POLLS, api).waitForSuccess(VAULT_NAME, inventoryRetrievalJob); assertThat(api.describeJob(VAULT_NAME, archiveRetrievalJob).getStatusCode()).isEqualTo(JobStatus.SUCCEEDED); assertThat(api.describeJob(VAULT_NAME, inventoryRetrievalJob).getStatusCode()).isEqualTo(JobStatus.SUCCEEDED); }
