mirror of https://github.com/apache/jclouds.git
JCLOUDS-1005: Retry on 500 and 503 errors
This requires rewriting the URL for b2_upload_file and b2_upload_part requests.
This commit is contained in:
parent
f66e0a3fcc
commit
2ff68fc79e
|
@ -48,6 +48,8 @@ public final class B2ApiMetadata extends BaseHttpApiMetadata {
|
||||||
public static Properties defaultProperties() {
|
public static Properties defaultProperties() {
|
||||||
Properties properties = BaseHttpApiMetadata.defaultProperties();
|
Properties properties = BaseHttpApiMetadata.defaultProperties();
|
||||||
properties.setProperty(Constants.PROPERTY_SESSION_INTERVAL, String.valueOf(TimeUnit.HOURS.toSeconds(1)));
|
properties.setProperty(Constants.PROPERTY_SESSION_INTERVAL, String.valueOf(TimeUnit.HOURS.toSeconds(1)));
|
||||||
|
properties.setProperty(Constants.PROPERTY_IDEMPOTENT_METHODS, "DELETE,GET,HEAD,OPTIONS,POST,PUT");
|
||||||
|
properties.setProperty(Constants.PROPERTY_RETRY_DELAY_START, String.valueOf(TimeUnit.SECONDS.toMillis(1)));
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,11 @@ import org.jclouds.Constants;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.b2.B2Api;
|
import org.jclouds.b2.B2Api;
|
||||||
import org.jclouds.b2.domain.Authorization;
|
import org.jclouds.b2.domain.Authorization;
|
||||||
|
import org.jclouds.b2.filters.B2RetryHandler;
|
||||||
import org.jclouds.b2.filters.RequestAuthorization;
|
import org.jclouds.b2.filters.RequestAuthorization;
|
||||||
import org.jclouds.b2.handlers.ParseB2ErrorFromJsonContent;
|
import org.jclouds.b2.handlers.ParseB2ErrorFromJsonContent;
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
@ -57,6 +59,11 @@ public final class B2HttpApiModule extends HttpApiModule<B2Api> {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseB2ErrorFromJsonContent.class);
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseB2ErrorFromJsonContent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindRetryHandlers() {
|
||||||
|
bind(HttpRetryHandler.class).annotatedWith(ServerError.class).to(B2RetryHandler.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static Supplier<Authorization> provideAuthorizationSupplier(final B2Api b2Api) {
|
static Supplier<Authorization> provideAuthorizationSupplier(final B2Api b2Api) {
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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.b2.filters;
|
||||||
|
|
||||||
|
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||||
|
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.b2.B2Api;
|
||||||
|
import org.jclouds.b2.domain.GetUploadPartResponse;
|
||||||
|
import org.jclouds.b2.domain.UploadUrlResponse;
|
||||||
|
import org.jclouds.http.HttpCommand;
|
||||||
|
import org.jclouds.http.HttpException;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.net.HttpHeaders;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public final class B2RetryHandler extends BackoffLimitedRetryHandler implements HttpRequestFilter {
|
||||||
|
private final B2Api api;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
B2RetryHandler(B2Api api) {
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||||
|
HttpRequest.Builder<?> builder = request.toBuilder();
|
||||||
|
|
||||||
|
// B2 requires retrying on a different storage node for uploads
|
||||||
|
String path = request.getEndpoint().getPath();
|
||||||
|
if (path.startsWith("/b2api/v1/b2_upload_file")) {
|
||||||
|
String bucketId = path.split("/")[4];
|
||||||
|
UploadUrlResponse uploadUrl = api.getObjectApi().getUploadUrl(bucketId);
|
||||||
|
builder.endpoint(uploadUrl.uploadUrl())
|
||||||
|
.replaceHeader(HttpHeaders.AUTHORIZATION, uploadUrl.authorizationToken());
|
||||||
|
} else if (path.startsWith("/b2api/v1/b2_upload_part")) {
|
||||||
|
String fileId = path.split("/")[4];
|
||||||
|
GetUploadPartResponse uploadUrl = api.getMultipartApi().getUploadPartUrl(fileId);
|
||||||
|
builder.endpoint(uploadUrl.uploadUrl())
|
||||||
|
.replaceHeader(HttpHeaders.AUTHORIZATION, uploadUrl.authorizationToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||||
|
boolean retry = false;
|
||||||
|
try {
|
||||||
|
byte[] data = closeClientButKeepContentStream(response);
|
||||||
|
switch (response.getStatusCode()) {
|
||||||
|
case 500:
|
||||||
|
case 503:
|
||||||
|
retry = super.shouldRetryRequest(command, response);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
releasePayload(response);
|
||||||
|
}
|
||||||
|
return retry;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue