You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@jclouds.apache.org by 李 煜东 <li...@hotmail.com> on 2019/03/15 13:41:36 UTC
答复: How to set local properties in jclouds?
Hi Andrea,
Thank you for your replying. In my case, I need to set different MAX_RETRIES for specific POST request.
overrides.setProperty(Constants.PROPERTY_MAX_RETRIES, Integer.toString(100)); makes all requests retry for a same number of times.
Could you give me a example on that?
Thanks and best regards,
Yudong
________________________________
发件人: Andrea Turli <an...@gmail.com>
发送时间: 2019年3月15日 18:38
收件人: user@jclouds.apache.org
主题: Re: How to set local properties in jclouds?
Hi Li Yudong,
I think you can do something similar to https://github.com/jclouds/jclouds-examples/blob/master/compute-basics/src/main/java/org/jclouds/examples/compute/basics/MainApp.java#L267
adding something like this to the properties overrides you pass to your Context
overrides.setProperty(Constants.PROPERTY_MAX_RETRIES, Integer.toString(100));
HTH,
Andrea
On Fri, Mar 15, 2019 at 11:21 AM liyudong123@hotmail.com<ma...@hotmail.com> <li...@hotmail.com>> wrote:
Hi,
As jclouds Documentation-Configuration describes, properties can be set before context built. What about local properties for example I'd like to set PROPERTY_MAX_RETRIES for a single command, is that possible?
Thanks
Li Yudong
Re: How to set local properties in jclouds?
Posted by Ignasi Barrera <na...@apache.org>.
It's not directly possible to configure max retries per command, but with a
little bit of code, you can do it.
First, let's create a custom retry handler that will read a custom
configured value for each command. Custom values will be configured via
context properties as follows:
// If the API method has a '@Named' annotation, use the value in the
annoattion to identify the method
overrides.setProperty("jclouds.max-retries.services:list, "5");
// Otherqise use the fully qualified class name
overrides.setProperty("jclouds.max-retries.org.jclouds.foo.bar.ApiClassName,
"10");
Then create the handler that will read the custom properties and apply the
configured max retries:
import static com.google.common.base.Optional.fromNullable;import
static com.google.common.collect.Maps.transformValues;import static
org.jclouds.util.Maps2.transformKeys;
import java.io.IOException;import java.util.Map;import java.util.regex.Pattern;
import javax.inject.Inject;
import org.jclouds.http.HttpCommand;import
org.jclouds.http.HttpResponse;import
org.jclouds.http.handlers.BackoffLimitedRetryHandler;import
org.jclouds.rest.config.InvocationConfig;import
org.jclouds.rest.internal.GeneratedHttpRequest;import
org.jclouds.util.Predicates2;
import com.google.common.base.Function;import
com.google.common.base.Optional;import
com.google.common.base.Predicate;
public class CustomRetryHandler extends BackoffLimitedRetryHandler {
private static final String PREFIX = "jclouds.max-retries.";
private final InvocationConfig invocationConfig;
private final Map<String, Integer> retriesPerCommand;
@Inject
CustomRetryHandler(InvocationConfig invocationConfig,
Function<Predicate<String>, Map<String, String>> propsFilter) {
this.invocationConfig = invocationConfig;
this.retriesPerCommand = maxRetries(propsFilter);
}
@Override
public boolean shouldRetryRequest(HttpCommand command, IOException error) {
Optional<Integer> customRetry = getMaxRetriesForCommand(command);
if (!customRetry.isPresent()) {
return super.shouldRetryRequest(command, error);
}
return waitIfNeeded(command, customRetry.get());
}
@Override
public boolean shouldRetryRequest(HttpCommand command, HttpResponse
response) {
Optional<Integer> customRetry = getMaxRetriesForCommand(command);
if (!customRetry.isPresent()) {
return super.shouldRetryRequest(command, response);
}
return waitIfNeeded(command, customRetry.get());
}
private Optional<Integer> getMaxRetriesForCommand(HttpCommand command) {
GeneratedHttpRequest request = (GeneratedHttpRequest)
command.getCurrentRequest();
String commandName =
invocationConfig.getCommandName(request.getInvocation());
return fromNullable(retriesPerCommand.get(commandName));
}
private boolean waitIfNeeded(HttpCommand command, Integer maxRetries) {
command.incrementFailureCount();
if (!command.isReplayable()) {
logger.error("Cannot retry after server error, command is not
replayable: %1$s", command);
return false;
} else if (command.getFailureCount() > maxRetries) {
logger.error("Cannot retry after server error, command has
exceeded retry limit %1$d: %2$s", maxRetries,
command);
return false;
} else {
imposeBackoffExponentialDelay(command.getFailureCount(),
"server error: " + command.toString());
return true;
}
}
private static Map<String, Integer>
maxRetries(Function<Predicate<String>, Map<String, String>> filter) {
Map<String, String> retryProps =
filter.apply(Predicates2.startsWith(PREFIX));
Map<String, Integer> intsByName = transformValues(retryProps,
new Function<String, Integer>() {
public Integer apply(String input) {
return Integer.valueOf(String.valueOf(input));
}
});
return transformKeys(intsByName, new Function<String, String>() {
public String apply(String input) {
return input.replaceFirst(Pattern.quote(PREFIX), "");
}
});
}
}
Then, configure a Guice module that will set up the custom retry handler:
import org.jclouds.http.HttpRetryHandler;import
org.jclouds.http.annotation.ServerError;import
com.google.inject.AbstractModule;
public class CustomRetriesModule extends AbstractModule {
@Override
protected void configure() {
bind(HttpRetryHandler.class).annotatedWith(ServerError.class).to(CustomRetryHandler.class);
}
}
And finally, when creating the Context, add that custom module to the list
of modules:
ContextBuilder.NewBuilder(...)
.overrodes(overrides)
.modules(ImmutableSet.of(new CustomRetriesModule(), ...)
...
HTH!
I.
On Fri, 15 Mar 2019 at 14:44, 李 煜东 <li...@hotmail.com> wrote:
> Hi Andrea,
>
> Thank you for your replying. In my case, I need to set different
> MAX_RETRIES for specific POST request.
>
> overrides.setProperty(Constants.PROPERTY_MAX_RETRIES,
> Integer.toString(100)); makes all requests retry for a same number of
> times.
>
> Could you give me a example on that?
>
> Thanks and best regards,
> Yudong
> ------------------------------
> *发件人:* Andrea Turli <an...@gmail.com>
> *发送时间:* 2019年3月15日 18:38
> *收件人:* user@jclouds.apache.org
> *主题:* Re: How to set local properties in jclouds?
>
> Hi Li Yudong,
>
> I think you can do something similar to
> https://github.com/jclouds/jclouds-examples/blob/master/compute-basics/src/main/java/org/jclouds/examples/compute/basics/MainApp.java#L267
>
> adding something like this to the properties overrides you pass to your
> Context
>
> overrides.setProperty(Constants.PROPERTY_MAX_RETRIES,
> Integer.toString(100));
>
> HTH,
> Andrea
>
> On Fri, Mar 15, 2019 at 11:21 AM liyudong123@hotmail.com <
> liyudong123@hotmail.com> wrote:
>
> Hi,
>
> As jclouds Documentation-Configuration describes, properties can be set
> before context built. What about local properties for example I'd like to
> set PROPERTY_MAX_RETRIES for a single command, is that possible?
>
> Thanks
> Li Yudong
>
>