mirror of https://github.com/apache/jclouds.git
Merge pull request #1125 from jclouds/redundant-fallback
Redundant fallback
This commit is contained in:
commit
b7f5999a22
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.vcloud.functions;
|
package org.jclouds.vcloud.functions;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.filter;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
|
||||||
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
@ -29,13 +30,8 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.concurrent.ExceptionParsingListenableFuture;
|
|
||||||
import org.jclouds.concurrent.Futures;
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
|
||||||
import org.jclouds.util.Iterables2;
|
|
||||||
import org.jclouds.vcloud.VCloudAsyncClient;
|
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||||
import org.jclouds.vcloud.VCloudMediaType;
|
import org.jclouds.vcloud.VCloudMediaType;
|
||||||
import org.jclouds.vcloud.domain.CatalogItem;
|
import org.jclouds.vcloud.domain.CatalogItem;
|
||||||
|
@ -44,7 +40,6 @@ import org.jclouds.vcloud.domain.VAppTemplate;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -53,34 +48,20 @@ import com.google.common.base.Throwables;
|
||||||
public class VAppTemplatesForCatalogItems implements Function<Iterable<CatalogItem>, Iterable<VAppTemplate>> {
|
public class VAppTemplatesForCatalogItems implements Function<Iterable<CatalogItem>, Iterable<VAppTemplate>> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
public Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
private final VCloudAsyncClient aclient;
|
private final VCloudAsyncClient aclient;
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
private final NullOnAuthorizationException NullOnAuthorizationException;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
static class NullOnAuthorizationException implements Function<Exception, VAppTemplate> {
|
|
||||||
|
|
||||||
public VAppTemplate apply(Exception from) {
|
|
||||||
if (from instanceof AuthorizationException) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw Throwables.propagate(from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
VAppTemplatesForCatalogItems(VCloudAsyncClient aclient,
|
VAppTemplatesForCatalogItems(VCloudAsyncClient aclient, @Named(PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
|
||||||
NullOnAuthorizationException NullOnAuthorizationException) {
|
|
||||||
this.aclient = aclient;
|
this.aclient = aclient;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.NullOnAuthorizationException = NullOnAuthorizationException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<VAppTemplate> apply(Iterable<CatalogItem> from) {
|
public Iterable<VAppTemplate> apply(Iterable<CatalogItem> from) {
|
||||||
return Iterables2.concreteCopy(filter(transformParallel(filter(from, new Predicate<CatalogItem>() {
|
return filter(transformParallel(filter(from, new Predicate<CatalogItem>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(CatalogItem input) {
|
public boolean apply(CatalogItem input) {
|
||||||
|
@ -91,12 +72,10 @@ public class VAppTemplatesForCatalogItems implements Function<Iterable<CatalogIt
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<VAppTemplate> apply(CatalogItem from) {
|
public Future<VAppTemplate> apply(CatalogItem from) {
|
||||||
return new ExceptionParsingListenableFuture<VAppTemplate>(Futures.makeListenable(VCloudAsyncClient.class
|
return aclient.getVAppTemplateClient().getVAppTemplate(from.getEntity().getHref());
|
||||||
.cast(aclient).getVAppTemplateClient().getVAppTemplate(from.getEntity().getHref()), executor),
|
|
||||||
NullOnAuthorizationException);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, executor, null, logger, "vappTemplates in"), Predicates.notNull()));
|
}, executor, null, logger, "vappTemplates in"), Predicates.notNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/**
|
|
||||||
* 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.concurrent;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms the exceptions in a future upon get
|
|
||||||
*
|
|
||||||
* Temporarily here until the following is resolved: <a
|
|
||||||
* href="http://code.google.com/p/guava-libraries/issues/detail?id=310"> guava issue 310</a>
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public class ExceptionParsingListenableFuture<T> implements ListenableFuture<T> {
|
|
||||||
|
|
||||||
private final ListenableFuture<T> future;
|
|
||||||
private final Function<Exception, T> function;
|
|
||||||
|
|
||||||
public static <T> ExceptionParsingListenableFuture<T> create(ListenableFuture<T> future,
|
|
||||||
Function<Exception, T> function) {
|
|
||||||
return new ExceptionParsingListenableFuture<T>(future, function);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExceptionParsingListenableFuture(ListenableFuture<T> future, Function<Exception, T> function) {
|
|
||||||
this.future = checkNotNull(future);
|
|
||||||
this.function = checkNotNull(function);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
|
||||||
return future.cancel(mayInterruptIfRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get() throws InterruptedException, ExecutionException {
|
|
||||||
try {
|
|
||||||
return future.get();
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw ie;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return attemptConvert(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private T attemptConvert(Exception e) {
|
|
||||||
if (e instanceof ExecutionException && e.getCause() instanceof Exception)
|
|
||||||
return function.apply((Exception) e.getCause());
|
|
||||||
return function.apply(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
try {
|
|
||||||
return future.get(timeout, unit);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw ie;
|
|
||||||
} catch (TimeoutException te) {
|
|
||||||
throw te;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return attemptConvert(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCancelled() {
|
|
||||||
return future.isCancelled();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDone() {
|
|
||||||
return future.isDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(Runnable listener, Executor exec) {
|
|
||||||
future.addListener(listener, exec);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
/**
|
|
||||||
* 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.concurrent;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests behavior of FutureExceptionParser
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit")
|
|
||||||
public class FutureExceptionParserTest {
|
|
||||||
ExecutorService executorService = MoreExecutors.sameThreadExecutor();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGet() throws InterruptedException, ExecutionException {
|
|
||||||
Future<?> future = createFuture(new RuntimeException("foo"));
|
|
||||||
assertEquals(future.get(), "foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = Exception.class)
|
|
||||||
public void testGetUnmatched() throws InterruptedException, ExecutionException {
|
|
||||||
Future<?> future = createFuture(new Exception("foo"));
|
|
||||||
assertEquals(future.get(), "foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetLongTimeUnit() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
Future<?> future = createFuture(new RuntimeException("foo"));
|
|
||||||
assertEquals(future.get(1, TimeUnit.SECONDS), "foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = Exception.class)
|
|
||||||
public void testGetLongTimeUnitUnmatched() throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
Future<?> future = createFuture(new Exception("foo"));
|
|
||||||
assertEquals(future.get(1, TimeUnit.SECONDS), "foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings( { "unchecked", "rawtypes" })
|
|
||||||
private Future<?> createFuture(final Exception exception) {
|
|
||||||
ListenableFuture<?> future = Futures.makeListenable(executorService.submit(new Callable<String>() {
|
|
||||||
|
|
||||||
public String call() throws Exception {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "throwException(" + exception + ")";
|
|
||||||
}
|
|
||||||
}), executorService);
|
|
||||||
|
|
||||||
future = new ExceptionParsingListenableFuture(future, new Function<Exception, String>() {
|
|
||||||
|
|
||||||
public String apply(Exception from) {
|
|
||||||
if (Iterables.size(Iterables.filter(Throwables.getCausalChain(from), RuntimeException.class)) >= 1)
|
|
||||||
return from.getMessage();
|
|
||||||
throw Throwables.propagate(from);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.vcloud.director.v1_5.functions;
|
package org.jclouds.vcloud.director.v1_5.functions;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.filter;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
|
||||||
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
@ -29,12 +30,8 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.concurrent.ExceptionParsingListenableFuture;
|
|
||||||
import org.jclouds.concurrent.Futures;
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
|
||||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
|
import org.jclouds.vcloud.director.v1_5.domain.CatalogItem;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
||||||
|
@ -42,7 +39,6 @@ import org.jclouds.vcloud.director.v1_5.user.VCloudDirectorAsyncApi;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author danikov
|
* @author danikov
|
||||||
|
@ -51,29 +47,14 @@ import com.google.common.base.Throwables;
|
||||||
public class VAppTemplatesForCatalogItems implements Function<Iterable<CatalogItem>, Iterable<? extends VAppTemplate>> {
|
public class VAppTemplatesForCatalogItems implements Function<Iterable<CatalogItem>, Iterable<? extends VAppTemplate>> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
public Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
private final VCloudDirectorAsyncApi aapi;
|
private final VCloudDirectorAsyncApi aapi;
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
private final NullOnAuthorizationException NullOnAuthorizationException;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
static class NullOnAuthorizationException implements Function<Exception, VAppTemplate> {
|
|
||||||
|
|
||||||
public VAppTemplate apply(Exception from) {
|
|
||||||
if (from instanceof AuthorizationException) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw Throwables.propagate(from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
VAppTemplatesForCatalogItems(VCloudDirectorAsyncApi aapi,
|
VAppTemplatesForCatalogItems(VCloudDirectorAsyncApi aapi, @Named(PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
|
||||||
NullOnAuthorizationException NullOnAuthorizationException) {
|
|
||||||
this.aapi = aapi;
|
this.aapi = aapi;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.NullOnAuthorizationException = NullOnAuthorizationException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -89,9 +70,7 @@ public class VAppTemplatesForCatalogItems implements Function<Iterable<CatalogIt
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<? extends VAppTemplate> apply(CatalogItem from) {
|
public Future<? extends VAppTemplate> apply(CatalogItem from) {
|
||||||
return new ExceptionParsingListenableFuture<VAppTemplate>(Futures.makeListenable(VCloudDirectorAsyncApi.class
|
return aapi.getVAppTemplateApi().get(from.getEntity().getHref());
|
||||||
.cast(aapi).getVAppTemplateApi().get(from.getEntity().getHref()), executor),
|
|
||||||
NullOnAuthorizationException);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, executor, null, logger, "vappTemplates in");
|
}, executor, null, logger, "vappTemplates in");
|
||||||
|
|
Loading…
Reference in New Issue