mirror of https://github.com/apache/jclouds.git
process timeouts based on @Named annotations
This commit is contained in:
parent
4fbb70be7b
commit
95b1849199
|
@ -117,9 +117,18 @@ public class BlockOnFuture implements Function<ListenableFuture<?>, Object> {
|
|||
|
||||
// override timeout by values configured in properties(in ms)
|
||||
private Optional<Long> timeoutInNanos(Invokable<?, ?> invoked, Map<String, Long> timeouts) {
|
||||
String className = enclosingType.getRawType().getSimpleName();
|
||||
Optional<Long> timeoutMillis = fromNullable(timeouts.get(className + "." + invoked.getName())).or(
|
||||
fromNullable(timeouts.get(className))).or(fromNullable(timeouts.get("default")));
|
||||
Optional<Long> defaultMillis = fromNullable(timeouts.get("default"));
|
||||
Optional<Long> timeoutMillis;
|
||||
if (invoked.isAnnotationPresent(Named.class)) {
|
||||
String commandName = invoked.getAnnotation(Named.class).value();
|
||||
timeoutMillis = fromNullable(timeouts.get(commandName)).or(defaultMillis);
|
||||
} else {
|
||||
// TODO: remove old logic, once Named annotations are present on all methods
|
||||
String className = enclosingType.getRawType().getSimpleName().replace("AsyncClient", "Client")
|
||||
.replace("AsyncApi", "Api");
|
||||
timeoutMillis = fromNullable(timeouts.get(className + "." + invoked.getName())).or(
|
||||
fromNullable(timeouts.get(className))).or(defaultMillis);
|
||||
}
|
||||
if (timeoutMillis.isPresent())
|
||||
return Optional.of(TimeUnit.MILLISECONDS.toNanos(timeoutMillis.get()));
|
||||
return Optional.absent();
|
||||
|
|
|
@ -101,11 +101,11 @@ public class InvokeHttpMethod<S, A> implements Function<Invocation, Object> {
|
|||
if (isFuture(in.getInvokable())) {
|
||||
return createFuture(in);
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
Invokable async = checkNotNull(sync2AsyncInvokables.getIfPresent(in.getInvokable()), "invokable %s not in %s",
|
||||
in.getInvokable(), sync2AsyncInvokables);
|
||||
checkState(isFuture(async), "not a future: %s", async);
|
||||
return blocker.create(enclosingType, in).apply(createFuture(Invocation.create(async, in.getArgs())));
|
||||
Invocation async = Invocation.create(
|
||||
checkNotNull(sync2AsyncInvokables.getIfPresent(in.getInvokable()), "invokable %s not in %s",
|
||||
in.getInvokable(), sync2AsyncInvokables), in.getArgs());
|
||||
checkState(isFuture(async.getInvokable()), "not a future: %s", async);
|
||||
return blocker.create(enclosingType, async).apply(createFuture(async));
|
||||
}
|
||||
|
||||
private boolean isFuture(Invokable<?, ?> in) {
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.rest.internal;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.reflect.Invocation;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", singleThreaded = true)
|
||||
public class BlockOnFutureTest {
|
||||
|
||||
static ListenableFuture<String> future;
|
||||
|
||||
public static class ThingAsyncApi {
|
||||
public ListenableFuture<String> get() {
|
||||
return future;
|
||||
}
|
||||
|
||||
@Named("ns:get")
|
||||
public ListenableFuture<String> namedGet() {
|
||||
return future;
|
||||
}
|
||||
}
|
||||
|
||||
private TypeToken<ThingAsyncApi> enclosingType;
|
||||
private Invocation get;
|
||||
private Invocation namedGet;
|
||||
|
||||
@BeforeClass
|
||||
void setupInvocations() throws SecurityException, NoSuchMethodException {
|
||||
enclosingType = TypeToken.of(ThingAsyncApi.class);
|
||||
get = Invocation.create(enclosingType.method(ThingAsyncApi.class.getDeclaredMethod("get")), ImmutableList.of());
|
||||
namedGet = Invocation.create(enclosingType.method(ThingAsyncApi.class.getDeclaredMethod("namedGet")),
|
||||
ImmutableList.of());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@BeforeMethod
|
||||
void createMockedFuture() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
future = createMock(ListenableFuture.class);
|
||||
expect(future.get(250000000, TimeUnit.NANOSECONDS)).andReturn("foo");
|
||||
replay(future);
|
||||
}
|
||||
|
||||
public void testUnnamedMethodWithDefaultPropTimeout() throws Exception {
|
||||
Function<ListenableFuture<?>, Object> withOverride = new BlockOnFuture(ImmutableMap.of("default", 250L),
|
||||
enclosingType, get);
|
||||
assertEquals(withOverride.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
public void testUnnamedMethodWithClassPropTimeout() throws Exception {
|
||||
Function<ListenableFuture<?>, Object> withOverride = new BlockOnFuture(ImmutableMap.of("default", 50L,
|
||||
"ThingApi", 250L), enclosingType, get);
|
||||
assertEquals(withOverride.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
public void testUnnamedMethodWithMethodPropTimeout() throws Exception {
|
||||
Function<ListenableFuture<?>, Object> withOverride = new BlockOnFuture(ImmutableMap.of("default", 50L,
|
||||
"ThingApi", 100L, "ThingApi.get", 250L), enclosingType, get);
|
||||
assertEquals(withOverride.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUnnamedMethodWithNoTimeoutsCallGetDirectly() throws Exception {
|
||||
future = createMock(ListenableFuture.class);
|
||||
expect(future.get()).andReturn("foo");
|
||||
replay(future);
|
||||
|
||||
Function<ListenableFuture<?>, Object> noOverrides = new BlockOnFuture(ImmutableMap.<String, Long> of(),
|
||||
enclosingType, get);
|
||||
|
||||
assertEquals(noOverrides.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
public void testNamedMethodWithDefaultPropTimeout() throws Exception {
|
||||
Function<ListenableFuture<?>, Object> withOverride = new BlockOnFuture(ImmutableMap.of("default", 250L),
|
||||
enclosingType, namedGet);
|
||||
assertEquals(withOverride.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
public void testNamedMethodWithMethodPropTimeout() throws Exception {
|
||||
Function<ListenableFuture<?>, Object> withOverride = new BlockOnFuture(ImmutableMap.of("default", 50L,
|
||||
"ThingApi", 100L, "ns:get", 250L), enclosingType, namedGet);
|
||||
assertEquals(withOverride.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testNamedMethodWithNoTimeoutsCallGetDirectly() throws Exception {
|
||||
future = createMock(ListenableFuture.class);
|
||||
expect(future.get()).andReturn("foo");
|
||||
replay(future);
|
||||
|
||||
Function<ListenableFuture<?>, Object> noOverrides = new BlockOnFuture(ImmutableMap.<String, Long> of(),
|
||||
enclosingType, namedGet);
|
||||
|
||||
assertEquals(noOverrides.apply(future), "foo");
|
||||
verify(future);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue