mirror of https://github.com/apache/jclouds.git
merge with upstream master, resolving conflicts in SecurityGroupClientExpectTest
This commit is contained in:
commit
d3f0e64de1
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* 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.openstack.services;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* An extension of a {@link ServiceType service}. In order for us to understand
|
||||
* the context of the extension, we must consider the <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* >extensions call</a>.
|
||||
*
|
||||
* <br/>
|
||||
* For our purposes, the minimal context of an extension is the type of the
|
||||
* service it extends ex. {@link ServiceType#COMPUTE}, and its namespace ex. <a
|
||||
* href
|
||||
* ="http://docs.openstack.org/ext/keypairs/api/v1.1">http://docs.openstack.org
|
||||
* /ext/keypairs/api/v1.1</a>.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
* @see ServiceType
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* />
|
||||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext/ext_keypairs.html" />
|
||||
*/
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface Extension {
|
||||
|
||||
/**
|
||||
* the service type this is an extension of.
|
||||
*
|
||||
* <h3>note</h3>
|
||||
*
|
||||
* This isn't necessarily one of the built-in {@link ServiceType services},
|
||||
* it could be an extension of a custom service.
|
||||
*
|
||||
* @return the service type this is an extension of.
|
||||
*
|
||||
*/
|
||||
String of();
|
||||
|
||||
/**
|
||||
* namespace ex. <a href
|
||||
* ="http://docs.openstack.org/ext/keypairs/api/v1.1">http
|
||||
* ://docs.openstack.org /ext/keypairs/api/v1.1</a>.
|
||||
*
|
||||
* @return the namespace of the extension
|
||||
*/
|
||||
String namespace();
|
||||
|
||||
}
|
|
@ -35,8 +35,11 @@ import javax.inject.Named;
|
|||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.util.Optionals2;
|
||||
import org.jclouds.util.Throwables2;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -51,14 +54,15 @@ import com.google.inject.ProvisionException;
|
|||
public class SyncProxy implements InvocationHandler {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T proxy(Class<T> clazz, Object async,
|
||||
public static <T> T proxy(Function<Object, Optional<Object>> optionalConverter, Class<T> clazz, Object async,
|
||||
@Named("sync") LoadingCache<ClassMethodArgs, Object> delegateMap,
|
||||
Map<Class<?>, Class<?>> sync2Async, Map<String, Long> timeouts) throws IllegalArgumentException, SecurityException,
|
||||
NoSuchMethodException {
|
||||
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz },
|
||||
new SyncProxy(clazz, async, delegateMap, sync2Async, timeouts));
|
||||
new SyncProxy(optionalConverter, clazz, async, delegateMap, sync2Async, timeouts));
|
||||
}
|
||||
|
||||
private final Function<Object, Optional<Object>> optionalConverter;
|
||||
private final Object delegate;
|
||||
private final Class<?> declaring;
|
||||
private final Map<Method, Method> methodMap;
|
||||
|
@ -69,10 +73,11 @@ public class SyncProxy implements InvocationHandler {
|
|||
private static final Set<Method> objectMethods = ImmutableSet.copyOf(Object.class.getMethods());
|
||||
|
||||
@Inject
|
||||
private SyncProxy(Class<?> declaring, Object async,
|
||||
private SyncProxy(Function<Object, Optional<Object>> optionalConverter, Class<?> declaring, Object async,
|
||||
@Named("sync") LoadingCache<ClassMethodArgs, Object> delegateMap, Map<Class<?>,
|
||||
Class<?>> sync2Async, final Map<String, Long> timeouts)
|
||||
throws SecurityException, NoSuchMethodException {
|
||||
this.optionalConverter = optionalConverter;
|
||||
this.delegateMap = delegateMap;
|
||||
this.delegate = async;
|
||||
this.declaring = declaring;
|
||||
|
@ -125,10 +130,19 @@ public class SyncProxy implements InvocationHandler {
|
|||
} else if (method.getName().equals("toString")) {
|
||||
return this.toString();
|
||||
} else if (method.isAnnotationPresent(Delegate.class)) {
|
||||
Class<?> asyncClass = sync2Async.get(method.getReturnType());
|
||||
checkState(asyncClass != null, "please configure corresponding async class for " + method.getReturnType()
|
||||
Class<?> syncClass = Optionals2.returnTypeOrTypeOfOptional(method);
|
||||
// get the return type of the asynchronous class associated with this client
|
||||
// ex. FloatingIPClient is associated with FloatingIPAsyncClient
|
||||
Class<?> asyncClass = sync2Async.get(syncClass);
|
||||
checkState(asyncClass != null, "please configure corresponding async class for " + syncClass
|
||||
+ " in your RestClientModule");
|
||||
// pass any parameters necessary to get a relevant instance of that async class
|
||||
// ex. getClientForRegion("north") might return an instance whose endpoint is
|
||||
// different that "south"
|
||||
Object returnVal = delegateMap.get(new ClassMethodArgs(asyncClass, method, args));
|
||||
if (Optionals2.isReturnTypeOptional(method)){
|
||||
return optionalConverter.apply(returnVal);
|
||||
}
|
||||
return returnVal;
|
||||
} else if (syncMethodMap.containsKey(method)) {
|
||||
return syncMethodMap.get(method).invoke(delegate, args);
|
||||
|
|
|
@ -71,19 +71,19 @@ public class BinderUtils {
|
|||
* interface for the sync client (ex. LoginClient)
|
||||
* @param asyncClientType
|
||||
* interface for the async client (ex. LoginAsyncClient)
|
||||
* @param delegates
|
||||
* @param sync2Async
|
||||
* presuming your clients are annotated with @Delegate, contains the sync to async
|
||||
* classes relating to these methods
|
||||
*/
|
||||
public static <S, A> void bindClientAndAsyncClient(Binder binder, Class<S> syncClientType, Class<A> asyncClientType,
|
||||
Map<Class<?>, Class<?>> delegates) {
|
||||
bindClient(binder, syncClientType, asyncClientType, delegates);
|
||||
Map<Class<?>, Class<?>> sync2Async) {
|
||||
bindClient(binder, syncClientType, asyncClientType, sync2Async);
|
||||
bindAsyncClient(binder, asyncClientType);
|
||||
}
|
||||
|
||||
public static <K, V> void bindClient(Binder binder, Class<K> syncClientType, Class<V> asyncClientType,
|
||||
Map<Class<?>, Class<?>> delegates) {
|
||||
Provider<K> asyncProvider = new ClientProvider<K, V>(syncClientType, asyncClientType, delegates);
|
||||
Map<Class<?>, Class<?>> sync2Async) {
|
||||
Provider<K> asyncProvider = new ClientProvider<K, V>(syncClientType, asyncClientType, sync2Async);
|
||||
binder.requestInjection(asyncProvider);
|
||||
binder.bind(syncClientType).toProvider(asyncProvider);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.concurrent.internal.SyncProxy;
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -59,17 +61,18 @@ public class ClientProvider<S, A> implements Provider<S> {
|
|||
@Singleton
|
||||
public S get() {
|
||||
A client = (A) injector.getInstance(Key.get(asyncClientType));
|
||||
Function<Object, Optional<Object>> optionalConverter = injector.getInstance(Key.get(new TypeLiteral<Function<Object, Optional<Object>>>() {
|
||||
}));
|
||||
LoadingCache<ClassMethodArgs, Object> delegateMap = injector.getInstance(Key.get(
|
||||
new TypeLiteral<LoadingCache<ClassMethodArgs, Object>>() {
|
||||
}, Names.named("sync")));
|
||||
Map<String, Long> timeoutsMap = injector.getInstance(Key.get(new TypeLiteral<Map<String, Long>>() {
|
||||
}, Names.named("TIMEOUTS")));
|
||||
try {
|
||||
return (S) SyncProxy.proxy(syncClientType, client, delegateMap, sync2Async,
|
||||
injector.getInstance(Key.get(new TypeLiteral<Map<String, Long>>() {
|
||||
}, Names.named("TIMEOUTS"))));
|
||||
return (S) SyncProxy.proxy(optionalConverter, syncClientType, client, delegateMap, sync2Async,
|
||||
timeoutsMap);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : "should have propagated";
|
||||
return null;
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,10 @@ import com.google.inject.TypeLiteral;
|
|||
import com.google.inject.name.Names;
|
||||
import org.jclouds.concurrent.internal.SyncProxy;
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
import org.jclouds.util.Optionals2;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
@ -61,19 +64,19 @@ public class CreateClientForCaller extends CacheLoader<ClassMethodArgs, Object>
|
|||
|
||||
@Override
|
||||
public Object load(ClassMethodArgs from) throws ExecutionException {
|
||||
Class<?> syncClass = from.getMethod().getReturnType();
|
||||
Class<?> syncClass = Optionals2.returnTypeOrTypeOfOptional(from.getMethod());
|
||||
Class<?> asyncClass = sync2Async.get(syncClass);
|
||||
checkState(asyncClass != null, "configuration error, sync class " + syncClass + " not mapped to an async class");
|
||||
Object asyncClient = asyncMap.get(from);
|
||||
checkState(asyncClient != null, "configuration error, sync client for " + from + " not found");
|
||||
Function<Object, Optional<Object>> optionalConverter = injector.getInstance(Key.get(new TypeLiteral<Function<Object, Optional<Object>>>() {
|
||||
}));
|
||||
Map<String, Long> timeoutsMap = injector.getInstance(Key.get(new TypeLiteral<Map<String, Long>>() {
|
||||
}, Names.named("TIMEOUTS")));
|
||||
try {
|
||||
return SyncProxy.proxy(syncClass, asyncClient, delegateMap.get(), sync2Async,
|
||||
injector.getInstance(Key.get(new TypeLiteral<Map<String, Long>>() {
|
||||
}, Names.named("TIMEOUTS"))));
|
||||
return SyncProxy.proxy(optionalConverter, syncClass, asyncClient, delegateMap.get(), sync2Async, timeoutsMap);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : "should have propagated";
|
||||
return null;
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,8 +31,11 @@ import org.jclouds.location.config.LocationModule;
|
|||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
@ -55,14 +58,14 @@ public class RestClientModule<S, A> extends AbstractModule {
|
|||
|
||||
protected final Class<A> asyncClientType;
|
||||
protected final Class<S> syncClientType;
|
||||
protected final Map<Class<?>, Class<?>> delegates;
|
||||
protected final Map<Class<?>, Class<?>> sync2Async;
|
||||
protected final AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
|
||||
|
||||
public RestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
|
||||
Map<Class<?>, Class<?>> delegates) {
|
||||
Map<Class<?>, Class<?>> sync2Async) {
|
||||
this.asyncClientType = asyncClientType;
|
||||
this.syncClientType = syncClientType;
|
||||
this.delegates = delegates;
|
||||
this.sync2Async = sync2Async;
|
||||
}
|
||||
|
||||
public RestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
|
||||
|
@ -77,6 +80,7 @@ public class RestClientModule<S, A> extends AbstractModule {
|
|||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<Function<Object, Optional<Object>>>(){}).to(ImplicitOptionalConverter.class);
|
||||
// this will help short circuit scenarios that can otherwise lock out users
|
||||
bind(new TypeLiteral<AtomicReference<AuthorizationException>>(){}).toInstance(authException);
|
||||
// Ensures the restcontext can be looked up without generic types.
|
||||
|
@ -136,7 +140,7 @@ public class RestClientModule<S, A> extends AbstractModule {
|
|||
|
||||
protected void bindClient() {
|
||||
BinderUtils.bindClient(binder(), syncClientType, asyncClientType,
|
||||
delegates);
|
||||
sync2Async);
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,7 +149,7 @@ public class RestClientModule<S, A> extends AbstractModule {
|
|||
@Named("sync")
|
||||
LoadingCache<ClassMethodArgs, Object> provideSyncDelegateMap(
|
||||
CreateClientForCaller createClientForCaller) {
|
||||
createClientForCaller.sync2Async = delegates;
|
||||
createClientForCaller.sync2Async = sync2Async;
|
||||
return CacheBuilder.newBuilder().build(createClientForCaller);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* 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.functions;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AlwaysPresentImplicitOptionalConverter implements ImplicitOptionalConverter {
|
||||
|
||||
@Override
|
||||
public Optional<Object> apply(Object input) {
|
||||
return Optional.of(input);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* 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.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ImplementedBy(AlwaysPresentImplicitOptionalConverter.class)
|
||||
public interface ImplicitOptionalConverter extends Function<Object, Optional<Object>> {
|
||||
|
||||
}
|
|
@ -41,9 +41,11 @@ import org.jclouds.logging.Logger;
|
|||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.util.Optionals2;
|
||||
import org.jclouds.util.Throwables2;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
@ -97,6 +99,7 @@ public class AsyncRestClientProxy<T> implements InvocationHandler {
|
|||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final Function<Object, Optional<Object>> optionalConverter;
|
||||
private final LoadingCache<ClassMethodArgs, Object> delegateMap;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -104,6 +107,8 @@ public class AsyncRestClientProxy<T> implements InvocationHandler {
|
|||
public AsyncRestClientProxy(Injector injector, Factory factory, RestAnnotationProcessor<T> util,
|
||||
TypeLiteral<T> typeLiteral, @Named("async") LoadingCache<ClassMethodArgs, Object> delegateMap) {
|
||||
this.injector = injector;
|
||||
this.optionalConverter = injector.getInstance(Key.get(new TypeLiteral<Function<Object, Optional<Object>>>() {
|
||||
}));
|
||||
this.annotationProcessor = util;
|
||||
this.declaring = (Class<T>) typeLiteral.getRawType();
|
||||
this.commandFactory = factory;
|
||||
|
@ -144,7 +149,12 @@ public class AsyncRestClientProxy<T> implements InvocationHandler {
|
|||
}
|
||||
|
||||
public Object propagateContextToDelegate(Method method, Object[] args) throws ExecutionException {
|
||||
return delegateMap.get(new ClassMethodArgs(method.getReturnType(), method, args));
|
||||
Class<?> asyncClass = Optionals2.returnTypeOrTypeOfOptional(method);
|
||||
Object returnVal = delegateMap.get(new ClassMethodArgs(asyncClass, method, args));
|
||||
if (Optionals2.isReturnTypeOptional(method)){
|
||||
return optionalConverter.apply(returnVal);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
public Object lookupValueFromGuice(Method method) {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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.util;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class Optionals2 {
|
||||
|
||||
public static Class<?> returnTypeOrTypeOfOptional(Method method) {
|
||||
boolean optional = isReturnTypeOptional(method);
|
||||
Class<?> syncClass;
|
||||
if (optional) {
|
||||
ParameterizedType futureType = ParameterizedType.class.cast(method.getGenericReturnType());
|
||||
// TODO: error checking in case this is a type, not a class.
|
||||
syncClass = Class.class.cast(futureType.getActualTypeArguments()[0]);
|
||||
} else {
|
||||
syncClass = method.getReturnType();
|
||||
}
|
||||
return syncClass;
|
||||
}
|
||||
|
||||
public static boolean isReturnTypeOptional(Method method) {
|
||||
boolean optional = method.getReturnType().isAssignableFrom(Optional.class);
|
||||
return optional;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,13 +32,14 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.jclouds.concurrent.Futures;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.internal.ClassMethodArgs;
|
||||
import org.jclouds.rest.functions.AlwaysPresentImplicitOptionalConverter;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -185,7 +186,7 @@ public class SyncProxyTest {
|
|||
public void setUp() throws IllegalArgumentException, SecurityException, NoSuchMethodException {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
sync = SyncProxy.proxy(Sync.class, new Async(), cache, ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
sync = SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), Sync.class, new Async(), cache, ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
ImmutableMap.of("Sync.takeXMillisecondsPropOverride", 250L));
|
||||
// just to warm up
|
||||
sync.string();
|
||||
|
@ -260,7 +261,7 @@ public class SyncProxyTest {
|
|||
IOException {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
SyncProxy.proxy(SyncWrongException.class, new Async(), cache, ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), SyncWrongException.class, new Async(), cache, ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
ImmutableMap.<String, Long> of());
|
||||
}
|
||||
|
||||
|
@ -280,7 +281,7 @@ public class SyncProxyTest {
|
|||
IOException {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
SyncProxy.proxy(SyncNoTimeOut.class, new Async(), cache, ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), SyncNoTimeOut.class, new Async(), cache, ImmutableMap.<Class<?>, Class<?>> of(),
|
||||
ImmutableMap.<String, Long> of());
|
||||
}
|
||||
|
||||
|
@ -301,7 +302,7 @@ public class SyncProxyTest {
|
|||
public void testClassOverridePropTimeout() throws Exception {
|
||||
LoadingCache<ClassMethodArgs, Object> cache = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.<Object> constant(null)));
|
||||
final SyncClassOverride sync2 = SyncProxy.proxy(SyncClassOverride.class, new Async(), cache,
|
||||
final SyncClassOverride sync2 = SyncProxy.proxy(new AlwaysPresentImplicitOptionalConverter(), SyncClassOverride.class, new Async(), cache,
|
||||
ImmutableMap.<Class<?>, Class<?>> of(), ImmutableMap.<String, Long> of("SyncClassOverride", 100L));
|
||||
|
||||
assertEquals(sync2.takeXMillisecondsPropOverride(200), "foo");
|
||||
|
|
|
@ -135,6 +135,7 @@ import org.jclouds.rest.binders.BindMapToMatrixParams;
|
|||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
import org.jclouds.rest.binders.BindToStringPayload;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.jclouds.xml.XMLParser;
|
||||
import org.testng.Assert;
|
||||
|
@ -144,6 +145,7 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -184,8 +186,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
protected void configure() {
|
||||
super.configure();
|
||||
bind(new TypeLiteral<Supplier<URI>>() {
|
||||
}).annotatedWith(Localhost2.class).toInstance(
|
||||
Suppliers.ofInstance(URI.create("http://localhost:1111")));
|
||||
}).annotatedWith(Localhost2.class).toInstance(Suppliers.ofInstance(URI.create("http://localhost:1111")));
|
||||
bind(IOExceptionRetryHandler.class).toInstance(IOExceptionRetryHandler.NEVER_RETRY);
|
||||
}
|
||||
|
||||
|
@ -212,6 +213,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
|
||||
@Delegate
|
||||
public Callee getCallee(@EndpointParam URI endpoint);
|
||||
|
||||
@Delegate
|
||||
public Optional<Callee> getOptionalCallee(@EndpointParam URI endpoint);
|
||||
}
|
||||
|
||||
@Timeout(duration = 10, timeUnit = TimeUnit.NANOSECONDS)
|
||||
|
@ -230,15 +234,19 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
|
||||
@Delegate
|
||||
public AsyncCallee getCallee(@EndpointParam URI endpoint);
|
||||
|
||||
@Delegate
|
||||
public Optional<AsyncCallee> getOptionalCallee(@EndpointParam URI endpoint);
|
||||
}
|
||||
|
||||
public void testAsyncDelegateIsLazyLoadedAndRequestIncludesVersionAndPath() throws InterruptedException, ExecutionException {
|
||||
public void testAsyncDelegateIsLazyLoadedAndRequestIncludesVersionAndPath() throws InterruptedException,
|
||||
ExecutionException {
|
||||
Injector child = injectorForCaller(new HttpCommandExecutorService() {
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> submit(HttpCommand command) {
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(),
|
||||
"GET http://localhost:9999/client/1/foo HTTP/1.1");
|
||||
"GET http://localhost:9999/client/1/foo HTTP/1.1");
|
||||
return Futures.immediateFuture(HttpResponse.builder().build());
|
||||
}
|
||||
|
||||
|
@ -255,13 +263,14 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
|
||||
}
|
||||
|
||||
public void testDelegateIsLazyLoadedAndRequestIncludesVersionAndPath() throws InterruptedException, ExecutionException {
|
||||
public void testDelegateIsLazyLoadedAndRequestIncludesVersionAndPath() throws InterruptedException,
|
||||
ExecutionException {
|
||||
Injector child = injectorForCaller(new HttpCommandExecutorService() {
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> submit(HttpCommand command) {
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(),
|
||||
"GET http://localhost:1111/client/1/foo HTTP/1.1");
|
||||
"GET http://localhost:1111/client/1/foo HTTP/1.1");
|
||||
return Futures.immediateFuture(HttpResponse.builder().build());
|
||||
}
|
||||
|
||||
|
@ -279,14 +288,13 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
public void testAsyncDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPath() throws InterruptedException, ExecutionException {
|
||||
public void testAsyncDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPath() throws InterruptedException,
|
||||
ExecutionException {
|
||||
Injector child = injectorForCaller(new HttpCommandExecutorService() {
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> submit(HttpCommand command) {
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(),
|
||||
"GET http://howdyboys/client/1/foo HTTP/1.1");
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1");
|
||||
return Futures.immediateFuture(HttpResponse.builder().build());
|
||||
}
|
||||
|
||||
|
@ -305,13 +313,77 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
|
||||
}
|
||||
|
||||
public void testDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPath() throws InterruptedException, ExecutionException {
|
||||
public void testAsyncDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPathOptionalPresent()
|
||||
throws InterruptedException, ExecutionException {
|
||||
Injector child = injectorForCaller(new HttpCommandExecutorService() {
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> submit(HttpCommand command) {
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(),
|
||||
"GET http://howdyboys/client/1/foo HTTP/1.1");
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1");
|
||||
return Futures.immediateFuture(HttpResponse.builder().build());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
child.getInstance(AsyncCallee.class);
|
||||
assert false : "Callee shouldn't be bound yet";
|
||||
} catch (ConfigurationException e) {
|
||||
|
||||
}
|
||||
|
||||
child.getInstance(AsyncCaller.class).getOptionalCallee(URI.create("http://howdyboys")).get().onePath("foo").get();
|
||||
|
||||
assertEquals(child.getInstance(AsyncCaller.class).getURI(), URI.create("http://localhost:1111"));
|
||||
|
||||
}
|
||||
|
||||
public void testAsyncDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPathCanOverrideOptionalBehaviour()
|
||||
throws InterruptedException, ExecutionException {
|
||||
Injector child = injectorForCaller(new HttpCommandExecutorService() {
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> submit(HttpCommand command) {
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1");
|
||||
return Futures.immediateFuture(HttpResponse.builder().build());
|
||||
}
|
||||
|
||||
}, new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ImplicitOptionalConverter.class).toInstance(new ImplicitOptionalConverter() {
|
||||
|
||||
@Override
|
||||
public Optional<Object> apply(Object input) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
child.getInstance(AsyncCallee.class);
|
||||
assert false : "Callee shouldn't be bound yet";
|
||||
} catch (ConfigurationException e) {
|
||||
|
||||
}
|
||||
|
||||
assert !child.getInstance(AsyncCaller.class).getOptionalCallee(URI.create("http://howdyboys")).isPresent();
|
||||
|
||||
assertEquals(child.getInstance(AsyncCaller.class).getURI(), URI.create("http://localhost:1111"));
|
||||
|
||||
}
|
||||
|
||||
public void testDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPath() throws InterruptedException,
|
||||
ExecutionException {
|
||||
Injector child = injectorForCaller(new HttpCommandExecutorService() {
|
||||
|
||||
@Override
|
||||
public Future<HttpResponse> submit(HttpCommand command) {
|
||||
assertEquals(command.getCurrentRequest().getRequestLine(), "GET http://howdyboys/client/1/foo HTTP/1.1");
|
||||
return Futures.immediateFuture(HttpResponse.builder().build());
|
||||
}
|
||||
|
||||
|
@ -328,11 +400,20 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
|
||||
}
|
||||
|
||||
private Injector injectorForCaller(HttpCommandExecutorService service) {
|
||||
private Injector injectorForCaller(HttpCommandExecutorService service, Module... modules) {
|
||||
|
||||
RestContextSpec<Caller, AsyncCaller> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "",
|
||||
"userfoo", null, Caller.class, AsyncCaller.class, ImmutableSet.<Module> of(new MockModule(service),
|
||||
new NullLoggingModule(), new CallerModule()));
|
||||
RestContextSpec<Caller, AsyncCaller> contextSpec = contextSpec(
|
||||
"test",
|
||||
"http://localhost:9999",
|
||||
"1",
|
||||
"",
|
||||
"",
|
||||
"userfoo",
|
||||
null,
|
||||
Caller.class,
|
||||
AsyncCaller.class,
|
||||
ImmutableSet.<Module> builder().add(new MockModule(service)).add(new NullLoggingModule())
|
||||
.add(new CallerModule()).addAll(ImmutableSet.<Module> copyOf(modules)).build());
|
||||
|
||||
return createContextBuilder(contextSpec).buildInjector();
|
||||
|
||||
|
@ -1822,9 +1903,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
public void oneTransformerWithContext() throws SecurityException, NoSuchMethodException {
|
||||
RestAnnotationProcessor<TestTransformers> processor = factory(TestTransformers.class);
|
||||
Method method = TestTransformers.class.getMethod("oneTransformerWithContext");
|
||||
GeneratedHttpRequest<TestTransformers> request = GeneratedHttpRequest.<TestTransformers>requestBuilder().method("GET")
|
||||
.endpoint(URI.create("http://localhost")).declaring(TestTransformers.class).javaMethod(method)
|
||||
.args(new Object[] {}).build();
|
||||
GeneratedHttpRequest<TestTransformers> request = GeneratedHttpRequest.<TestTransformers> requestBuilder()
|
||||
.method("GET").endpoint(URI.create("http://localhost")).declaring(TestTransformers.class)
|
||||
.javaMethod(method).args(new Object[] {}).build();
|
||||
Function<HttpResponse, ?> transformer = processor.createResponseParser(method, request);
|
||||
assertEquals(transformer.getClass(), ReturnStringIf200Context.class);
|
||||
assertEquals(((ReturnStringIf200Context) transformer).request, request);
|
||||
|
@ -2354,9 +2435,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
public void testCreateJAXBResponseParserWithAnnotation() throws SecurityException, NoSuchMethodException {
|
||||
RestAnnotationProcessor<TestJAXBResponseParser> processor = factory(TestJAXBResponseParser.class);
|
||||
Method method = TestJAXBResponseParser.class.getMethod("jaxbGetWithAnnotation");
|
||||
GeneratedHttpRequest<TestJAXBResponseParser> request = GeneratedHttpRequest.<TestJAXBResponseParser>requestBuilder()
|
||||
.method("GET").endpoint(URI.create("http://localhost")).declaring(TestJAXBResponseParser.class)
|
||||
.javaMethod(method).args(new Object[] {}).build();
|
||||
GeneratedHttpRequest<TestJAXBResponseParser> request = GeneratedHttpRequest
|
||||
.<TestJAXBResponseParser> requestBuilder().method("GET").endpoint(URI.create("http://localhost"))
|
||||
.declaring(TestJAXBResponseParser.class).javaMethod(method).args(new Object[] {}).build();
|
||||
Function<HttpResponse, ?> transformer = processor.createResponseParser(method, request);
|
||||
assertEquals(transformer.getClass(), ParseXMLWithJAXB.class);
|
||||
}
|
||||
|
@ -2365,9 +2446,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
public void testCreateJAXBResponseParserWithAcceptHeader() throws SecurityException, NoSuchMethodException {
|
||||
RestAnnotationProcessor<TestJAXBResponseParser> processor = factory(TestJAXBResponseParser.class);
|
||||
Method method = TestJAXBResponseParser.class.getMethod("jaxbGetWithAcceptHeader");
|
||||
GeneratedHttpRequest<TestJAXBResponseParser> request = GeneratedHttpRequest.<TestJAXBResponseParser>requestBuilder()
|
||||
.method("GET").endpoint(URI.create("http://localhost")).declaring(TestJAXBResponseParser.class)
|
||||
.javaMethod(method).args(new Object[] {}).build();
|
||||
GeneratedHttpRequest<TestJAXBResponseParser> request = GeneratedHttpRequest
|
||||
.<TestJAXBResponseParser> requestBuilder().method("GET").endpoint(URI.create("http://localhost"))
|
||||
.declaring(TestJAXBResponseParser.class).javaMethod(method).args(new Object[] {}).build();
|
||||
Function<HttpResponse, ?> transformer = processor.createResponseParser(method, request);
|
||||
assertEquals(transformer.getClass(), ParseXMLWithJAXB.class);
|
||||
}
|
||||
|
@ -2409,40 +2490,40 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testAddHostNullWithHost() throws Exception{
|
||||
assertNull(RestAnnotationProcessor.addHostIfMissing(null,null));
|
||||
public void testAddHostNullWithHost() throws Exception {
|
||||
assertNull(RestAnnotationProcessor.addHostIfMissing(null, null));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testAddHostWithHostHasNoHost() throws Exception{
|
||||
assertNull(RestAnnotationProcessor.addHostIfMissing(null,new URI("/no/host")));
|
||||
public void testAddHostWithHostHasNoHost() throws Exception {
|
||||
assertNull(RestAnnotationProcessor.addHostIfMissing(null, new URI("/no/host")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddHostNullOriginal() throws Exception{
|
||||
assertNull(RestAnnotationProcessor.addHostIfMissing(null,new URI("http://foo")));
|
||||
public void testAddHostNullOriginal() throws Exception {
|
||||
assertNull(RestAnnotationProcessor.addHostIfMissing(null, new URI("http://foo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddHostOriginalHasHost() throws Exception{
|
||||
public void testAddHostOriginalHasHost() throws Exception {
|
||||
|
||||
URI original = new URI("http://hashost/foo");
|
||||
URI result = RestAnnotationProcessor.addHostIfMissing(original,new URI("http://foo"));
|
||||
assertEquals(original,result);
|
||||
URI original = new URI("http://hashost/foo");
|
||||
URI result = RestAnnotationProcessor.addHostIfMissing(original, new URI("http://foo"));
|
||||
assertEquals(original, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddHostIfMissing() throws Exception{
|
||||
URI result = RestAnnotationProcessor.addHostIfMissing(new URI("/bar"),new URI("http://foo"));
|
||||
assertEquals(new URI("http://foo/bar"),result);
|
||||
public void testAddHostIfMissing() throws Exception {
|
||||
URI result = RestAnnotationProcessor.addHostIfMissing(new URI("/bar"), new URI("http://foo"));
|
||||
assertEquals(new URI("http://foo/bar"), result);
|
||||
}
|
||||
|
||||
DateService dateService = new SimpleDateFormatDateService();
|
||||
|
||||
@BeforeClass
|
||||
void setupFactory() {
|
||||
RestContextSpec<Callee, AsyncCallee> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "", "userfoo",
|
||||
null, Callee.class, AsyncCallee.class,
|
||||
RestContextSpec<Callee, AsyncCallee> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "",
|
||||
"userfoo", null, Callee.class, AsyncCallee.class,
|
||||
ImmutableSet.<Module> of(new MockModule(), new NullLoggingModule(), new AbstractModule() {
|
||||
|
||||
@Override
|
||||
|
@ -2453,7 +2534,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
}).annotatedWith(Names.named("bar")).toInstance(ImmutableSet.of("bar"));
|
||||
bind(new TypeLiteral<Supplier<URI>>() {
|
||||
}).annotatedWith(Localhost2.class).toInstance(
|
||||
Suppliers.ofInstance(URI.create("http://localhost:1111")));
|
||||
Suppliers.ofInstance(URI.create("http://localhost:1111")));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* 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.util;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test
|
||||
public class Optionals2Test {
|
||||
|
||||
public static interface Test {
|
||||
Optional<String> getOptional();
|
||||
|
||||
String getNotOptional();
|
||||
}
|
||||
|
||||
public void testReturnTypeOrTypeOfOptionalWhenOptional() throws SecurityException, NoSuchMethodException {
|
||||
Method method = Test.class.getMethod("getOptional");
|
||||
|
||||
assertEquals(Optionals2.returnTypeOrTypeOfOptional(method), String.class);
|
||||
}
|
||||
|
||||
public void testReturnTypeOrTypeOfOptionalWhenNotOptional() throws SecurityException, NoSuchMethodException {
|
||||
Method method = Test.class.getMethod("getNotOptional");
|
||||
|
||||
assertEquals(Optionals2.returnTypeOrTypeOfOptional(method), String.class);
|
||||
}
|
||||
|
||||
public void testIsReturnTypeOptionalWhenOptional() throws SecurityException, NoSuchMethodException {
|
||||
Method method = Test.class.getMethod("getOptional");
|
||||
|
||||
assertTrue(Optionals2.isReturnTypeOptional(method));
|
||||
}
|
||||
|
||||
public void testIsReturnTypeOptionalWhenNotOptional() throws SecurityException, NoSuchMethodException {
|
||||
Method method = Test.class.getMethod("getNotOptional");
|
||||
|
||||
assertFalse(Optionals2.isReturnTypeOptional(method));
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
|
|||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
|
@ -85,7 +86,7 @@ public interface NovaAsyncClient {
|
|||
* Provides asynchronous access to Floating IP features.
|
||||
*/
|
||||
@Delegate
|
||||
FloatingIPAsyncClient getFloatingIPClientForRegion(
|
||||
Optional<FloatingIPAsyncClient> getFloatingIPExtensionForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
|||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
|
@ -87,7 +88,7 @@ public interface NovaClient {
|
|||
* Provides synchronous access to Floating IP features.
|
||||
*/
|
||||
@Delegate
|
||||
FloatingIPClient getFloatingIPClientForRegion(
|
||||
Optional<FloatingIPClient> getFloatingIPExtensionForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Extension namespaces
|
||||
|
@ -27,8 +26,8 @@ import java.net.URI;
|
|||
* @see <a href= "http://nova.openstack.org/api_ext/" />
|
||||
*/
|
||||
public interface ExtensionNamespaces {
|
||||
public static URI KEYPAIRS = URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1");
|
||||
public static URI VOLUMES = URI.create("http://docs.openstack.org/ext/volumes/api/v1.1");
|
||||
public static URI SECURITY_GROUPS = URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1");
|
||||
public static URI FLOATING_IPS = URI.create("http://docs.openstack.org/ext/floating_ips/api/v1.1");
|
||||
public static final String KEYPAIRS = "http://docs.openstack.org/ext/keypairs/api/v1.1";
|
||||
public static final String VOLUMES = "http://docs.openstack.org/ext/volumes/api/v1.1";
|
||||
public static final String SECURITY_GROUPS = "http://docs.openstack.org/ext/securitygroups/api/v1.1";
|
||||
public static final String FLOATING_IPS = "http://docs.openstack.org/ext/floating_ips/api/v1.1";
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import javax.ws.rs.core.MediaType;
|
|||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||
import org.jclouds.openstack.services.Extension;
|
||||
import org.jclouds.openstack.services.ServiceType;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
|
@ -50,10 +52,13 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see FloatingIPClient
|
||||
* @author Jeremy Daggett
|
||||
* @see ExtensionAsyncClient
|
||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* />
|
||||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://wiki.openstack.org/os_api_floating_ip"/>
|
||||
*/
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IPS)
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface FloatingIPAsyncClient {
|
||||
|
@ -107,9 +112,7 @@ public interface FloatingIPAsyncClient {
|
|||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"addFloatingIp\":%7B\"address\":\"{address}\"%7D%7D")
|
||||
ListenableFuture<Void> addFloatingIP(
|
||||
@PathParam("server") String serverId,
|
||||
@PayloadParam("address") String address);
|
||||
ListenableFuture<Void> addFloatingIP(@PathParam("server") String serverId, @PayloadParam("address") String address);
|
||||
|
||||
/**
|
||||
* @see FloatingIPClient#removeFloatingIP
|
||||
|
@ -119,8 +122,6 @@ public interface FloatingIPAsyncClient {
|
|||
@Consumes
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Payload("%7B\"removeFloatingIp\":%7B\"address\":\"{address}\"%7D%7D")
|
||||
ListenableFuture<Void> removeFloatingIP(
|
||||
@PathParam("server") String serverId,
|
||||
@PayloadParam("address") String address);
|
||||
ListenableFuture<Void> removeFloatingIP(@PathParam("server") String serverId, @PayloadParam("address") String address);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.services.Extension;
|
||||
import org.jclouds.openstack.services.ServiceType;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Floating IPs.
|
||||
|
@ -31,6 +33,7 @@ import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
|||
* @see FloatingIPAsyncClient
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IPS)
|
||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||
public interface FloatingIPClient {
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ import javax.ws.rs.core.MediaType;
|
|||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||
import org.jclouds.openstack.services.Extension;
|
||||
import org.jclouds.openstack.services.ServiceType;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
|
@ -55,6 +57,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext/ext_keypairs.html" />
|
||||
*/
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface KeyPairAsyncClient {
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
||||
import org.jclouds.openstack.services.Extension;
|
||||
import org.jclouds.openstack.services.ServiceType;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Security Groups.
|
||||
|
@ -32,6 +34,7 @@ import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
|||
* @see KeyPairAsyncClient
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
|
||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||
public interface KeyPairClient {
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ import javax.ws.rs.core.MediaType;
|
|||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.services.Extension;
|
||||
import org.jclouds.openstack.services.ServiceType;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
|
@ -54,6 +56,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://wiki.openstack.org/os-security-groups" />
|
||||
*/
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SECURITY_GROUPS)
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface SecurityGroupAsyncClient {
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.services.Extension;
|
||||
import org.jclouds.openstack.services.ServiceType;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Security Groups.
|
||||
|
@ -32,6 +34,7 @@ import org.jclouds.openstack.nova.v1_1.domain.SecurityGroupRule;
|
|||
* @see SecurityGroupAsyncClient
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SECURITY_GROUPS)
|
||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||
public interface SecurityGroupClient {
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.util.Properties;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseServerListTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "PasswordAuthenticationExpectTest")
|
||||
public class PasswordAuthenticationExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class PasswordAuthenticationExpectTest extends BaseNovaClientExpectTest {
|
||||
|
||||
/**
|
||||
* this reflects the properties that a user would pass to createContext
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* 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.openstack.nova.v1_1.extensions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaAsyncClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseFloatingIPListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseFloatingIPTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Tests annotation parsing of {@code FloatingIPAsyncClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "FloatingIPAsyncClientExpectTest")
|
||||
public class FloatingIPAsyncClientExpectTest extends BaseNovaAsyncClientExpectTest {
|
||||
|
||||
public void testListFloatingIPsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listFloatingIPs = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(URI.create("https://compute.north.host/v1.1/3456/os-floating-ips"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listFloatingIPsResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/floatingip_list.json")).build();
|
||||
|
||||
NovaAsyncClient clientWhenFloatingIPsExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, listFloatingIPs, listFloatingIPsResponse);
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getConfiguredRegions(), ImmutableSet.of("North"));
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPExtensionForRegion("North").get().listFloatingIPs().get()
|
||||
.toString(), new ParseFloatingIPListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListFloatingIPsWhenResponseIs404() throws Exception {
|
||||
HttpRequest listFloatingIPs = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(URI.create("https://compute.north.host/v1.1/3456/os-floating-ips"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listFloatingIPsResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaAsyncClient clientWhenNoServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, listFloatingIPs, listFloatingIPsResponse);
|
||||
|
||||
assertTrue(clientWhenNoServersExist.getFloatingIPExtensionForRegion("North").get().listFloatingIPs().get()
|
||||
.isEmpty());
|
||||
}
|
||||
|
||||
public void testGetFloatingIPWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest getFloatingIP = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(URI.create("https://compute.north.host/v1.1/3456/os-floating-ips/1"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse getFloatingIPResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/floatingip_details.json")).build();
|
||||
|
||||
NovaAsyncClient clientWhenFloatingIPsExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, getFloatingIP, getFloatingIPResponse);
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPExtensionForRegion("North").get().getFloatingIP("1").get()
|
||||
.toString(), new ParseFloatingIPTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testGetFloatingIPWhenResponseIs404() throws Exception {
|
||||
HttpRequest getFloatingIP = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(URI.create("https://compute.north.host/v1.1/3456/os-floating-ips/1"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse getFloatingIPResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaAsyncClient clientWhenNoServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, getFloatingIP, getFloatingIPResponse);
|
||||
|
||||
assertNull(clientWhenNoServersExist.getFloatingIPExtensionForRegion("North").get().getFloatingIP("1").get());
|
||||
}
|
||||
|
||||
public void testAllocateWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest allocateFloatingIP = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint(URI.create("https://compute.north.host/v1.1/3456/os-floating-ips"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build())
|
||||
.payload(payloadFromStringWithContentType("{}", "application/json")).build();
|
||||
|
||||
HttpResponse allocateFloatingIPResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/floatingip_details.json")).build();
|
||||
|
||||
NovaAsyncClient clientWhenFloatingIPsExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, allocateFloatingIP, allocateFloatingIPResponse);
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPExtensionForRegion("North").get().allocate().get()
|
||||
.toString(), new ParseFloatingIPTest().expected().toString());
|
||||
|
||||
}
|
||||
|
||||
public void testAllocateWhenResponseIs404() throws Exception {
|
||||
HttpRequest allocateFloatingIP = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint(URI.create("https://compute.north.host/v1.1/3456/os-floating-ips"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build())
|
||||
.payload(payloadFromStringWithContentType("{}", "application/json")).build();
|
||||
|
||||
HttpResponse allocateFloatingIPResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaAsyncClient clientWhenNoServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, allocateFloatingIP, allocateFloatingIPResponse);
|
||||
|
||||
assertNull(clientWhenNoServersExist.getFloatingIPExtensionForRegion("North").get().allocate().get());
|
||||
}
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ import java.net.URI;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseFloatingIPListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseFloatingIPTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -41,7 +41,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "FloatingIPClientExpectTest")
|
||||
public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class FloatingIPClientExpectTest extends BaseNovaClientExpectTest {
|
||||
|
||||
public void testListFloatingIPsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listFloatingIPs = HttpRequest
|
||||
|
@ -64,7 +64,7 @@ public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
|||
assertEquals(clientWhenFloatingIPsExist.getConfiguredRegions(),
|
||||
ImmutableSet.of("North"));
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPClientForRegion("North")
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPExtensionForRegion("North").get()
|
||||
.listFloatingIPs().toString(), new ParseFloatingIPListTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
|||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listFloatingIPs, listFloatingIPsResponse);
|
||||
|
||||
assertTrue(clientWhenNoServersExist.getFloatingIPClientForRegion("North")
|
||||
assertTrue(clientWhenNoServersExist.getFloatingIPExtensionForRegion("North").get()
|
||||
.listFloatingIPs().isEmpty());
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
|||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
getFloatingIP, getFloatingIPResponse);
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPClientForRegion("North")
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPExtensionForRegion("North").get()
|
||||
.getFloatingIP("1").toString(),
|
||||
new ParseFloatingIPTest().expected().toString());
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
|||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
getFloatingIP, getFloatingIPResponse);
|
||||
|
||||
assertNull(clientWhenNoServersExist.getFloatingIPClientForRegion("North")
|
||||
assertNull(clientWhenNoServersExist.getFloatingIPExtensionForRegion("North").get()
|
||||
.getFloatingIP("1"));
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
|||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
allocateFloatingIP, allocateFloatingIPResponse);
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPClientForRegion("North")
|
||||
assertEquals(clientWhenFloatingIPsExist.getFloatingIPExtensionForRegion("North").get()
|
||||
.allocate().toString(),
|
||||
new ParseFloatingIPTest().expected().toString());
|
||||
|
||||
|
@ -178,7 +178,7 @@ public class FloatingIPClientExpectTest extends BaseNovaRestClientExpectTest {
|
|||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
allocateFloatingIP, allocateFloatingIPResponse);
|
||||
|
||||
assertNull(clientWhenNoServersExist.getFloatingIPClientForRegion("North")
|
||||
assertNull(clientWhenNoServersExist.getFloatingIPExtensionForRegion("North").get()
|
||||
.allocate());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.testng.Assert.assertTrue;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
|
@ -52,8 +53,10 @@ public class FloatingIPClientLiveTest extends BaseNovaClientLiveTest {
|
|||
@Test
|
||||
public void testListFloatingIPs() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
|
||||
FloatingIPClient client = context.getApi().getFloatingIPClientForRegion(regionId);
|
||||
Optional<FloatingIPClient> clientOption = context.getApi().getFloatingIPExtensionForRegion(regionId);
|
||||
if (!clientOption.isPresent())
|
||||
continue;
|
||||
FloatingIPClient client = clientOption.get();
|
||||
Set<FloatingIP> response = client.listFloatingIPs();
|
||||
assert null != response;
|
||||
assertTrue(response.size() >= 0);
|
||||
|
@ -73,7 +76,10 @@ public class FloatingIPClientLiveTest extends BaseNovaClientLiveTest {
|
|||
@Test
|
||||
public void testAllocateAndDeallocateFloatingIPs() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
FloatingIPClient client = context.getApi().getFloatingIPClientForRegion(regionId);
|
||||
Optional<FloatingIPClient> clientOption = context.getApi().getFloatingIPExtensionForRegion(regionId);
|
||||
if (!clientOption.isPresent())
|
||||
continue;
|
||||
FloatingIPClient client = clientOption.get();
|
||||
FloatingIP floatingIP = client.allocate();
|
||||
assertNotNull(floatingIP);
|
||||
|
||||
|
@ -101,7 +107,10 @@ public class FloatingIPClientLiveTest extends BaseNovaClientLiveTest {
|
|||
@Test
|
||||
public void testAddAndRemoveFloatingIp() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
FloatingIPClient client = context.getApi().getFloatingIPClientForRegion(regionId);
|
||||
Optional<FloatingIPClient> clientOption = context.getApi().getFloatingIPExtensionForRegion(regionId);
|
||||
if (!clientOption.isPresent())
|
||||
continue;
|
||||
FloatingIPClient client = clientOption.get();
|
||||
ServerClient serverClient = context.getApi().getServerClientForRegion(regionId);
|
||||
Server server = serverClient.createServer("test", imageIdForRegion(regionId), flavorRefForRegion(regionId));
|
||||
blockUntilServerActive(server.getId(), serverClient);
|
||||
|
|
|
@ -23,7 +23,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseKeyPairListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseKeyPairTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -40,7 +40,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "KeyPairClientExpectTest")
|
||||
public class KeyPairClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class KeyPairClientExpectTest extends BaseNovaClientExpectTest {
|
||||
|
||||
public void testListKeyPairsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listKeyPairs = HttpRequest
|
||||
|
|
|
@ -16,17 +16,22 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseSecurityGroupListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseSecurityGroupTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
@ -38,7 +43,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "SecurityGroupClientExpectTest")
|
||||
public class SecurityGroupClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class SecurityGroupClientExpectTest extends BaseNovaClientExpectTest {
|
||||
public void testListSecurityGroupsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listSecurityGroups = HttpRequest
|
||||
.builder()
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.net.URI;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseExtensionListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseExtensionTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -41,7 +41,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ExtensionClientExpectTest")
|
||||
public class ExtensionClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class ExtensionClientExpectTest extends BaseNovaClientExpectTest {
|
||||
|
||||
public void testListExtensionsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listExtensions = HttpRequest
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.net.URI;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseFlavorListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseFlavorTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -41,7 +41,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Test(groups = "unit", testName = "FlavorClientExpectTest")
|
||||
public class FlavorClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class FlavorClientExpectTest extends BaseNovaClientExpectTest {
|
||||
|
||||
public void testListFlavorsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listFlavors = HttpRequest
|
||||
|
|
|
@ -23,7 +23,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseImageTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseImageListTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -40,7 +40,7 @@ import static org.testng.Assert.assertTrue;
|
|||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ImageAsyncClientTest")
|
||||
public class ImageClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class ImageClientExpectTest extends BaseNovaClientExpectTest {
|
||||
public void testListImagesWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listImages = HttpRequest
|
||||
.builder()
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.net.URI;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseServerListTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ServerAsyncClientTest")
|
||||
public class ServerClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public class ServerClientExpectTest extends BaseNovaClientExpectTest {
|
||||
|
||||
public void testListServersWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listServers = HttpRequest.builder().method("GET").endpoint(
|
||||
|
|
|
@ -18,33 +18,32 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.internal;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.jclouds.rest.RestContextFactory.createContext;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.logging.config.NullLoggingModule;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextSpec;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Base class for writing KeyStone Rest Client Expect tests
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class BaseNovaAsyncClientTest<T> extends RestClientTest<T> {
|
||||
|
||||
@Override
|
||||
protected void checkFilters(HttpRequest request) {
|
||||
assertEquals(request.getFilters().size(), 1);
|
||||
assertEquals(request.getFilters().get(0).getClass(), AuthenticateRequest.class);
|
||||
public class BaseNovaAsyncClientExpectTest extends BaseNovaExpectTest<NovaAsyncClient> {
|
||||
public NovaAsyncClient createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
|
||||
RestContextSpec<NovaClient, NovaAsyncClient> contextSpec = new RestContextFactory(setupRestProperties())
|
||||
.createContextSpec(provider, identity, credential, new Properties());
|
||||
return createContext(contextSpec,
|
||||
ImmutableSet.<Module> of(new ExpectModule(fn), new NullLoggingModule(), module), props).getAsyncApi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestContextSpec<NovaClient, NovaAsyncClient> createContextSpec() {
|
||||
Properties props = new Properties();
|
||||
return new RestContextFactory().createContextSpec("openstack-nova", "accountId", "accessKey", props);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* 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.openstack.nova.v1_1.internal;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
|
||||
/**
|
||||
* Base class for writing KeyStone Rest Client Expect tests
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseNovaClientExpectTest extends BaseNovaExpectTest<NovaClient> {
|
||||
|
||||
}
|
|
@ -25,43 +25,22 @@ import org.jclouds.compute.ComputeServiceContextFactory;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.logging.config.NullLoggingModule;
|
||||
import org.jclouds.openstack.keystone.v2_0.internal.KeystoneFixture;
|
||||
import org.jclouds.rest.BaseRestClientExpectTest;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Base class for writing KeyStone Expect tests with the ComputeService abstraction
|
||||
* Base class for writing KeyStone Expect tests with the ComputeService
|
||||
* abstraction
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class BaseNovaComputeServiceExpectTest extends BaseRestClientExpectTest<ComputeService>
|
||||
{
|
||||
protected HttpRequest keystoneAuthWithUsernameAndPassword;
|
||||
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
||||
protected String authToken;
|
||||
protected HttpResponse responseWithKeystoneAccess;
|
||||
|
||||
public BaseNovaComputeServiceExpectTest()
|
||||
{
|
||||
provider = "openstack-nova";
|
||||
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
||||
credential);
|
||||
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
|
||||
credential);
|
||||
authToken = KeystoneFixture.INSTANCE.getAuthToken();
|
||||
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
|
||||
// now, createContext arg will need tenant prefix
|
||||
identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity;
|
||||
}
|
||||
|
||||
public class BaseNovaComputeServiceExpectTest extends BaseNovaExpectTest<ComputeService> {
|
||||
|
||||
@Override
|
||||
public ComputeService createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props)
|
||||
{
|
||||
public ComputeService createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
|
||||
return new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, identity, credential,
|
||||
ImmutableSet.<Module>of(new ExpectModule(fn), new NullLoggingModule(), module), props).getComputeService();
|
||||
ImmutableSet.<Module> of(new ExpectModule(fn), new NullLoggingModule(), module), props).getComputeService();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,20 @@ package org.jclouds.openstack.nova.v1_1.internal;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.keystone.v2_0.internal.KeystoneFixture;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.rest.BaseRestClientExpectTest;
|
||||
|
||||
/**
|
||||
* Base class for writing KeyStone Rest Client Expect tests
|
||||
* Base class for writing Nova Expect tests
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseNovaRestClientExpectTest extends BaseRestClientExpectTest<NovaClient> {
|
||||
public class BaseNovaExpectTest<T> extends BaseRestClientExpectTest<T> {
|
||||
protected HttpRequest keystoneAuthWithUsernameAndPassword;
|
||||
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
||||
protected String authToken;
|
||||
protected HttpResponse responseWithKeystoneAccess;
|
||||
|
||||
public BaseNovaRestClientExpectTest() {
|
||||
public BaseNovaExpectTest() {
|
||||
provider = "openstack-nova";
|
||||
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
||||
credential);
|
|
@ -74,7 +74,7 @@ public class AdminCatalogClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
assertEquals(client.getAdminCatalogClient().createCatalog(catalogRef.getHref(), source), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testGetCatalog() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
|
@ -90,7 +90,7 @@ public class AdminCatalogClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
assertEquals(client.getAdminCatalogClient().getCatalog(catalogRef.getHref()), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testModifyCatalog() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
|
@ -107,7 +107,7 @@ public class AdminCatalogClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
assertEquals(client.getAdminCatalogClient().updateCatalog(catalogRef.getHref(), expected), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testGetOwner() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
|
|
|
@ -51,7 +51,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
@Test(groups = { "unit", "media" }, singleThreaded = true, testName = "MediaClientExpectTest")
|
||||
public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTest {
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testCreateMedia() {
|
||||
URI uploadLink = URI.create(endpoint + "/vdc/e9cd3387-ac57-4d27-a481-9bee75e0690f/media");
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTes
|
|||
assertEquals(client.getMediaClient().createMedia(uploadLink, source), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testCloneMedia() {
|
||||
URI cloneUri = URI.create(endpoint + "/vdc/e9cd3387-ac57-4d27-a481-9bee75e0690f/action/cloneMedia");
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTes
|
|||
assertEquals(client.getMediaClient().cloneMedia(cloneUri, params), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testGetMedia() {
|
||||
URI mediaUri = URI.create(endpoint + "/media/794eb334-754e-4917-b5a0-5df85cbd61d1");
|
||||
|
||||
|
@ -211,7 +211,7 @@ public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTes
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testUpdateMedia() {
|
||||
URI mediaUri = URI.create(endpoint + "/media/794eb334-754e-4917-b5a0-5df85cbd61d1");
|
||||
|
||||
|
@ -345,7 +345,7 @@ public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTes
|
|||
assertEquals(client.getMediaClient().getMetadataClient().deleteMetadataEntry(mediaUri, "key"), expectedTask);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testGetOwner() {
|
||||
URI mediaUri = URI.create(endpoint + "/media/794eb334-754e-4917-b5a0-5df85cbd61d1");
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public class QueryClientExpectTest extends BaseVCloudDirectorRestClientExpectTes
|
|||
assertEquals(client.getQueryClient().catalogsQueryAll(), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testQueryAllCatalogReferences() {
|
||||
HttpRequest queryRequest = HttpRequest.builder()
|
||||
.method("GET")
|
||||
|
|
|
@ -74,7 +74,7 @@ public class VAppClientExpectTest extends BaseVCloudDirectorRestClientExpectTest
|
|||
public void before() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testGetVapp() {
|
||||
VCloudDirectorClient client = orderedRequestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
|
|
|
@ -80,6 +80,7 @@ public class VAppTemplateClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
|
||||
}
|
||||
|
||||
@Test(enabled = false)//TODO
|
||||
public void testVAppTemplate() {
|
||||
final String templateId = "/vAppTemplate/vappTemplate-ef4415e6-d413-4cbb-9262-f9bbec5f2ea9";
|
||||
URI uri = URI.create(endpoint + templateId);
|
||||
|
@ -117,7 +118,8 @@ public class VAppTemplateClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
client.getVAppTemplate(uri);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = VCloudDirectorException.class)
|
||||
//TODO
|
||||
@Test(enabled = false, expectedExceptions = VCloudDirectorException.class)
|
||||
public void testErrorEditVAppTemplate() {
|
||||
final String templateId = "/vAppTemplate/vappTemplate-ef4415e6-d413-4cbb-9262-f9bbec5f2ea9";
|
||||
URI uri = URI.create(endpoint + templateId);
|
||||
|
@ -252,6 +254,7 @@ public class VAppTemplateClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
client.relocateVappTemplate(uri, params);
|
||||
}
|
||||
|
||||
@Test(enabled = false)//TODO
|
||||
public void testCustomizationSection() {
|
||||
final String templateId = "/vAppTemplate/vappTemplate-ef4415e6-d413-4cbb-9262-f9bbec5f2ea9";
|
||||
URI uri = URI.create(endpoint + templateId);
|
||||
|
@ -272,7 +275,8 @@ public class VAppTemplateClientExpectTest extends BaseVCloudDirectorRestClientEx
|
|||
assertNotNull(task);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = VCloudDirectorException.class)
|
||||
//TODO
|
||||
@Test(enabled = false, expectedExceptions = VCloudDirectorException.class)
|
||||
public void testErrorGetCustomizationSection() {
|
||||
final String templateId = "/vAppTemplate/vappTemplate-ef4415e6-d413-4cbb-9262-f9bbec5f2ea9";
|
||||
URI uri = URI.create(endpoint + templateId);
|
||||
|
|
|
@ -293,7 +293,7 @@ public class VdcClientExpectTest extends BaseVCloudDirectorRestClientExpectTest
|
|||
assertEquals(client.getVdcClient().uploadVAppTemplate(vdcURI, params), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testCreateMedia() {
|
||||
URI vdcUri = URI.create(endpoint + "/vdc/e9cd3387-ac57-4d27-a481-9bee75e0690f");
|
||||
|
||||
|
@ -319,7 +319,7 @@ public class VdcClientExpectTest extends BaseVCloudDirectorRestClientExpectTest
|
|||
assertEquals(client.getVdcClient().createMedia(vdcUri, source), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)//TODO
|
||||
public void testCloneMedia() {
|
||||
URI vdcUri = URI.create(endpoint + "/vdc/e9cd3387-ac57-4d27-a481-9bee75e0690f");
|
||||
|
||||
|
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
package org.jclouds.virtualbox;
|
||||
|
||||
import static org.jclouds.Constants.*;
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_IMAGE_AUTHENTICATE_SUDO;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_IMAGE_LOGIN_USER;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
@ -60,12 +58,10 @@ public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
|
|||
properties.put(PROPERTY_API_VERSION, "4.1.4");
|
||||
|
||||
properties.put(PROPERTY_BUILD_VERSION, "4.1.8r75467");
|
||||
properties.put(PROPERTY_IDENTITY, "administrator");
|
||||
properties.put(PROPERTY_CREDENTIAL, "12345");
|
||||
|
||||
properties.put(PROPERTY_IMAGE_LOGIN_USER, "toor:password");
|
||||
properties.put(PROPERTY_IMAGE_AUTHENTICATE_SUDO, "true");
|
||||
|
||||
|
||||
properties.put(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> "
|
||||
+ "/install/vmlinuz noapic preseed/url=PRECONFIGURATION_URL "
|
||||
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + "HOSTNAME "
|
||||
|
@ -82,7 +78,7 @@ public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
|
|||
|
||||
properties.put(VIRTUALBOX_IMAGES_DESCRIPTOR, yamlDescriptor);
|
||||
|
||||
properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:8080/src/test/resources/preseed.cfg");
|
||||
properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:23232/preseed.cfg");
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
|
|||
NodeSpec nodeSpec = NodeSpec.builder().master(master).name(name).tag(tag).template(template).build();
|
||||
return cloneCreator.apply(nodeSpec);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ import org.jclouds.virtualbox.functions.IMachineToHardware;
|
|||
import org.jclouds.virtualbox.functions.IMachineToImage;
|
||||
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
|
||||
import org.jclouds.virtualbox.functions.IMachineToSshClient;
|
||||
import org.jclouds.virtualbox.functions.MastersCache;
|
||||
import org.jclouds.virtualbox.functions.MastersLoadingCache;
|
||||
import org.jclouds.virtualbox.functions.NodeCreator;
|
||||
import org.jclouds.virtualbox.functions.YamlImagesFromFileConfig;
|
||||
import org.jclouds.virtualbox.functions.admin.FileDownloadFromURI;
|
||||
|
@ -141,7 +141,7 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
}).to((Class) YamlImagesFromFileConfig.class);
|
||||
// the master machines cache
|
||||
bind(new TypeLiteral<LoadingCache<Image, Master>>() {
|
||||
}).to((Class) MastersCache.class);
|
||||
}).to((Class) MastersLoadingCache.class);
|
||||
// the master creating function
|
||||
bind(new TypeLiteral<Function<MasterSpec, IMachine>>() {
|
||||
}).to((Class) CreateAndInstallVm.class);
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -100,6 +99,7 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Fu
|
|||
.getVBox()
|
||||
.createMachine(settingsFile, vmSpec.getVmName(), vmSpec.getOsTypeId(), vmSpec.getVmId(),
|
||||
vmSpec.isForceOverwrite());
|
||||
|
||||
List<CloneOptions> options = new ArrayList<CloneOptions>();
|
||||
if (isLinkedClone)
|
||||
options.add(CloneOptions.Link);
|
||||
|
|
|
@ -44,12 +44,10 @@ import org.jclouds.virtualbox.util.MachineController;
|
|||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -62,7 +60,6 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
private final GuestAdditionsInstaller guestAdditionsInstaller;
|
||||
private final Predicate<SshClient> sshResponds;
|
||||
|
@ -75,7 +72,6 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
|
||||
@Inject
|
||||
public CreateAndInstallVm(
|
||||
Supplier<VirtualBoxManager> manager,
|
||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
||||
GuestAdditionsInstaller guestAdditionsInstaller,
|
||||
IMachineToNodeMetadata imachineToNodeMetadata,
|
||||
|
@ -83,7 +79,6 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
Function<IMachine, SshClient> sshClientForIMachine,
|
||||
MachineUtils machineUtils,
|
||||
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration, MachineController machineController) {
|
||||
this.manager = manager;
|
||||
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
this.sshResponds = sshResponds;
|
||||
this.sshClientForIMachine = sshClientForIMachine;
|
||||
|
@ -113,6 +108,7 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
|
||||
configureOsInstallationWithKeyboardSequence(vmName,
|
||||
installationKeySequence);
|
||||
|
||||
SshClient client = sshClientForIMachine.apply(vm);
|
||||
|
||||
logger.debug(">> awaiting installation to finish node(%s)", vmName);
|
||||
|
@ -121,8 +117,8 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
"timed out waiting for guest %s to be accessible via ssh",
|
||||
vmName);
|
||||
|
||||
//logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
|
||||
//checkState(guestAdditionsInstaller.apply(vm));
|
||||
logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
|
||||
checkState(guestAdditionsInstaller.apply(vm));
|
||||
|
||||
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
|
||||
|
||||
|
|
|
@ -23,17 +23,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule.machineToNodeState;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
|
|
|
@ -64,17 +64,20 @@ import com.google.common.base.Function;
|
|||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.AbstractLoadingCache;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Does most of the work wrt to creating the master image.
|
||||
* A {@link LoadingCache} for masters. If the requested master has been previously created this
|
||||
* returns it, if not it coordinates its creation including downloading isos and creating
|
||||
* cache/config directories.
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class MastersCache extends AbstractLoadingCache<Image, Master> {
|
||||
public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
|
||||
|
||||
// TODO parameterize
|
||||
public static final int MASTER_PORT = 2222;
|
||||
|
@ -94,7 +97,7 @@ public class MastersCache extends AbstractLoadingCache<Image, Master> {
|
|||
private String version;
|
||||
|
||||
@Inject
|
||||
public MastersCache(@Named(Constants.PROPERTY_BUILD_VERSION) String version,
|
||||
public MastersLoadingCache(@Named(Constants.PROPERTY_BUILD_VERSION) String version,
|
||||
@Named(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) String installationKeySequence,
|
||||
@Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function<MasterSpec, IMachine> masterLoader,
|
||||
Supplier<Map<Image, YamlImage>> yamlMapper, Supplier<VirtualBoxManager> manager,
|
|
@ -43,10 +43,12 @@ import org.jclouds.virtualbox.domain.NetworkInterfaceCard;
|
|||
import org.jclouds.virtualbox.domain.NetworkSpec;
|
||||
import org.jclouds.virtualbox.domain.NodeSpec;
|
||||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.jclouds.virtualbox.statements.DeleteGShadowLock;
|
||||
import org.jclouds.virtualbox.statements.SetIpAddress;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
@ -54,149 +56,140 @@ import org.virtualbox_4_1.VirtualBoxManager;
|
|||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* Creates nodes, by cloning a master vm and based on the provided {@link NodeSpec}. Must be
|
||||
* synchronized mainly because of snapshot creation (must be synchronized on a per-master-basis).
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class NodeCreator implements
|
||||
Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
|
||||
public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
|
||||
|
||||
// TODO parameterize
|
||||
public static final int NODE_PORT_INIT = 3000;
|
||||
// TODO parameterize
|
||||
public static final int NODE_PORT_INIT = 3000;
|
||||
|
||||
// TODO parameterize
|
||||
public static final String VMS_NETWORK = "33.33.33.";
|
||||
// TODO parameterize
|
||||
public static final String VMS_NETWORK = "33.33.33.";
|
||||
|
||||
// TODO parameterize
|
||||
public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
|
||||
// TODO parameterize
|
||||
public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
|
||||
|
||||
// TODO parameterize
|
||||
public static final boolean USE_LINKED = true;
|
||||
// TODO parameterize
|
||||
public static final boolean USE_LINKED = true;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Function<CloneSpec, IMachine> cloner;
|
||||
private final AtomicInteger nodePorts;
|
||||
private final AtomicInteger nodeIps;
|
||||
private MachineUtils machineUtils;
|
||||
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
|
||||
// TODO parameterize
|
||||
public static final ExecutionType EXECUTION_TYPE = ExecutionType.HEADLESS;
|
||||
|
||||
private final RunScriptOnNode.Factory scriptRunnerFactory;
|
||||
private final Supplier<NodeMetadata> hostSupplier;
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Function<CloneSpec, IMachine> cloner;
|
||||
private final AtomicInteger nodePorts;
|
||||
private final AtomicInteger nodeIps;
|
||||
private MachineUtils machineUtils;
|
||||
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
public NodeCreator(Supplier<VirtualBoxManager> manager,
|
||||
Function<CloneSpec, IMachine> cloner, MachineUtils machineUtils,
|
||||
Function<IMachine, NodeMetadata> imachineToNodeMetadata,
|
||||
RunScriptOnNode.Factory scriptRunnerFactory,
|
||||
Supplier<NodeMetadata> hostSupplier) {
|
||||
this.manager = manager;
|
||||
this.cloner = cloner;
|
||||
this.nodePorts = new AtomicInteger(NODE_PORT_INIT);
|
||||
this.nodeIps = new AtomicInteger(1);
|
||||
this.machineUtils = machineUtils;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
this.scriptRunnerFactory = scriptRunnerFactory;
|
||||
this.hostSupplier = hostSupplier;
|
||||
private final RunScriptOnNode.Factory scriptRunnerFactory;
|
||||
private final Supplier<NodeMetadata> hostSupplier;
|
||||
|
||||
}
|
||||
@Inject
|
||||
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
|
||||
MachineUtils machineUtils, Function<IMachine, NodeMetadata> imachineToNodeMetadata,
|
||||
RunScriptOnNode.Factory scriptRunnerFactory, Supplier<NodeMetadata> hostSupplier) {
|
||||
this.manager = manager;
|
||||
this.cloner = cloner;
|
||||
this.nodePorts = new AtomicInteger(NODE_PORT_INIT + 1);
|
||||
this.nodeIps = new AtomicInteger(1);
|
||||
this.machineUtils = machineUtils;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
this.scriptRunnerFactory = scriptRunnerFactory;
|
||||
this.hostSupplier = hostSupplier;
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
||||
}
|
||||
|
||||
checkNotNull(nodeSpec, "NodeSpec");
|
||||
@Override
|
||||
public synchronized NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
||||
|
||||
Master master = nodeSpec.getMaster();
|
||||
checkNotNull(master, "Master");
|
||||
checkNotNull(nodeSpec, "NodeSpec");
|
||||
|
||||
if (master.getMachine().getCurrentSnapshot() != null) {
|
||||
ISession session;
|
||||
try {
|
||||
session = manager.get().openMachineSession(master.getMachine());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"error opening vbox machine session: " + e.getMessage(),
|
||||
e);
|
||||
}
|
||||
session.getConsole().deleteSnapshot(
|
||||
master.getMachine().getCurrentSnapshot().getId());
|
||||
session.unlockMachine();
|
||||
}
|
||||
String masterNameWithoutPrefix = master.getSpec().getVmSpec()
|
||||
.getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
|
||||
Master master = nodeSpec.getMaster();
|
||||
checkNotNull(master, "Master");
|
||||
|
||||
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix
|
||||
+ "-" + nodeSpec.getTag() + "-" + nodeSpec.getName();
|
||||
if (master.getMachine().getCurrentSnapshot() != null) {
|
||||
ISession session;
|
||||
try {
|
||||
session = manager.get().openMachineSession(master.getMachine());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("error opening vbox machine session: " + e.getMessage(), e);
|
||||
}
|
||||
IProgress progress = session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId());
|
||||
progress.waitForCompletion(-1);
|
||||
session.unlockMachine();
|
||||
}
|
||||
String masterNameWithoutPrefix = master.getSpec().getVmSpec().getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
|
||||
|
||||
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName)
|
||||
.memoryMB(512).cleanUpMode(CleanupMode.Full)
|
||||
.forceOverwrite(true).build();
|
||||
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-"
|
||||
+ nodeSpec.getName();
|
||||
|
||||
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
|
||||
.forceOverwrite(true).build();
|
||||
|
||||
// CASE NAT + HOST-ONLY
|
||||
NetworkAdapter natAdapter = NetworkAdapter
|
||||
.builder()
|
||||
.networkAttachmentType(NetworkAttachmentType.NAT)
|
||||
.tcpRedirectRule("127.0.0.1", this.nodePorts.getAndIncrement(),
|
||||
"", 22).build();
|
||||
NetworkInterfaceCard natIfaceCard = NetworkInterfaceCard.builder()
|
||||
.addNetworkAdapter(natAdapter).slot(0L).build();
|
||||
// CASE NAT + HOST-ONLY
|
||||
NetworkAdapter natAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
|
||||
.tcpRedirectRule("127.0.0.1", this.nodePorts.getAndIncrement(), "", 22).build();
|
||||
NetworkInterfaceCard natIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(natAdapter).slot(0L).build();
|
||||
|
||||
NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder()
|
||||
.networkAttachmentType(NetworkAttachmentType.HostOnly)
|
||||
.staticIp(VMS_NETWORK + this.nodeIps.getAndIncrement()).build();
|
||||
NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.HostOnly)
|
||||
.staticIp(VMS_NETWORK + this.nodeIps.getAndIncrement()).build();
|
||||
|
||||
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder()
|
||||
.addNetworkAdapter(hostOnlyAdapter)
|
||||
.addHostInterfaceName(HOST_ONLY_IFACE_NAME).slot(1L).build();
|
||||
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(hostOnlyAdapter)
|
||||
.addHostInterfaceName(HOST_ONLY_IFACE_NAME).slot(1L).build();
|
||||
|
||||
NetworkSpec networkSpec = createNetworkSpecForHostOnlyNATNICs(natIfaceCard, hostOnlyIfaceCard);
|
||||
////
|
||||
NetworkSpec networkSpec = createNetworkSpecForHostOnlyNATNICs(natIfaceCard, hostOnlyIfaceCard);
|
||||
// //
|
||||
|
||||
// CASE BRIDGED
|
||||
//NetworkSpec networkSpec = createNetworkSpecForBridgedNIC();
|
||||
// CASE BRIDGED
|
||||
// NetworkSpec networkSpec = createNetworkSpecForBridgedNIC();
|
||||
|
||||
CloneSpec cloneSpec = CloneSpec.builder().linked(USE_LINKED)
|
||||
.master(master.getMachine()).network(networkSpec)
|
||||
.vm(cloneVmSpec).build();
|
||||
CloneSpec cloneSpec = CloneSpec.builder().linked(USE_LINKED).master(master.getMachine()).network(networkSpec)
|
||||
.vm(cloneVmSpec).build();
|
||||
|
||||
IMachine cloned = cloner.apply(cloneSpec);
|
||||
IMachine cloned = cloner.apply(cloneSpec);
|
||||
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI,
|
||||
"").apply(cloned);
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), EXECUTION_TYPE, "").apply(cloned);
|
||||
|
||||
// see DeleteGShadowLock for a detailed explanation
|
||||
machineUtils
|
||||
.runScriptOnNode(imachineToNodeMetadata.apply(cloned), new DeleteGShadowLock(), RunScriptOptions.NONE);
|
||||
|
||||
// CASE NAT + HOST-ONLY
|
||||
machineUtils.runScriptOnNode(imachineToNodeMetadata.apply(cloned),
|
||||
new SetIpAddress(hostOnlyIfaceCard), RunScriptOptions.NONE);
|
||||
////
|
||||
// CASE NAT + HOST-ONLY
|
||||
machineUtils.runScriptOnNode(imachineToNodeMetadata.apply(cloned), new SetIpAddress(hostOnlyIfaceCard),
|
||||
RunScriptOptions.NONE);
|
||||
// //
|
||||
|
||||
// TODO get credentials from somewhere else (they are also HC in
|
||||
// IMachineToSshClient)
|
||||
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned,
|
||||
cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
|
||||
|
||||
// TODO get credentials from somewhere else (they are also HC in
|
||||
// IMachineToSshClient)
|
||||
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(
|
||||
cloned, cloneName, LoginCredentials.builder().user("toor")
|
||||
.password("password").authenticateSudo(true).build());
|
||||
return nodeAndInitialCredentials;
|
||||
}
|
||||
|
||||
return nodeAndInitialCredentials;
|
||||
}
|
||||
private NetworkSpec createNetworkSpecForHostOnlyNATNICs(NetworkInterfaceCard natIfaceCard,
|
||||
NetworkInterfaceCard hostOnlyIfaceCard) {
|
||||
return NetworkSpec.builder().addNIC(natIfaceCard).addNIC(hostOnlyIfaceCard).build();
|
||||
}
|
||||
|
||||
private NetworkSpec createNetworkSpecForHostOnlyNATNICs(NetworkInterfaceCard natIfaceCard, NetworkInterfaceCard hostOnlyIfaceCard) {
|
||||
return NetworkSpec.builder().addNIC(natIfaceCard)
|
||||
.addNIC(hostOnlyIfaceCard).build();
|
||||
}
|
||||
private NetworkSpec createNetworkSpecForBridgedNIC() {
|
||||
List<BridgedIf> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(scriptRunnerFactory)
|
||||
.apply(hostSupplier.get());
|
||||
BridgedIf bridgedActiveInterface = checkNotNull(activeBridgedInterfaces.get(0), "activeBridgedIf");
|
||||
|
||||
private NetworkSpec createNetworkSpecForBridgedNIC() {
|
||||
List<BridgedIf> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(
|
||||
scriptRunnerFactory).apply(hostSupplier.get());
|
||||
BridgedIf bridgedActiveInterface = checkNotNull(
|
||||
activeBridgedInterfaces.get(0), "activeBridgedIf");
|
||||
NetworkAdapter bridgedAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.Bridged)
|
||||
.build();
|
||||
NetworkInterfaceCard bridgedNIC = NetworkInterfaceCard.builder().addNetworkAdapter(bridgedAdapter)
|
||||
.addHostInterfaceName(bridgedActiveInterface.getName()).slot(0L).build();
|
||||
|
||||
NetworkAdapter bridgedAdapter = NetworkAdapter.builder()
|
||||
.networkAttachmentType(NetworkAttachmentType.Bridged).build();
|
||||
NetworkInterfaceCard bridgedNIC = NetworkInterfaceCard.builder()
|
||||
.addNetworkAdapter(bridgedAdapter)
|
||||
.addHostInterfaceName(bridgedActiveInterface.getName())
|
||||
.slot(0L).build();
|
||||
|
||||
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(bridgedNIC)
|
||||
.build();
|
||||
return networkSpec;
|
||||
}
|
||||
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(bridgedNIC).build();
|
||||
return networkSpec;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ import com.google.common.base.Throwables;
|
|||
*/
|
||||
public class TakeSnapshotIfNotAlreadyAttached implements Function<IMachine, ISnapshot> {
|
||||
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
@ -49,7 +48,6 @@ public class TakeSnapshotIfNotAlreadyAttached implements Function<IMachine, ISna
|
|||
private String snapshotName;
|
||||
private String snapshotDesc;
|
||||
|
||||
|
||||
public TakeSnapshotIfNotAlreadyAttached(Supplier<VirtualBoxManager> manager, String snapshotName, String snapshotDesc) {
|
||||
this.manager = manager;
|
||||
this.snapshotName = snapshotName;
|
||||
|
@ -60,18 +58,34 @@ public class TakeSnapshotIfNotAlreadyAttached implements Function<IMachine, ISna
|
|||
public ISnapshot apply(@Nullable IMachine machine) {
|
||||
// Snapshot a machine
|
||||
ISession session = null;
|
||||
if(machine.getCurrentSnapshot() == null ) {
|
||||
try {
|
||||
session = manager.get().openMachineSession(machine);
|
||||
IProgress progress = session.getConsole().takeSnapshot(snapshotName, snapshotDesc);
|
||||
if (progress.getCompleted())
|
||||
logger.debug("Snapshot %s (description: %s) taken from %s", snapshotName, snapshotDesc, machine.getName());
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "Problem creating snapshot %s (descripton: %s) from machine %s", snapshotName, snapshotDesc, machine.getName());
|
||||
Throwables.propagate(e);
|
||||
assert false;
|
||||
} finally {
|
||||
session.unlockMachine();
|
||||
if (machine.getCurrentSnapshot() == null) {
|
||||
int retries = 10;
|
||||
while (true) {
|
||||
try {
|
||||
session = manager.get().openMachineSession(machine);
|
||||
IProgress progress = session.getConsole().takeSnapshot(snapshotName, snapshotDesc);
|
||||
progress.waitForCompletion(-1);
|
||||
logger.debug("Snapshot %s (description: %s) taken from %s", snapshotName, snapshotDesc,
|
||||
machine.getName());
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
logger.error(e,
|
||||
"Problem creating snapshot (too many retries) %s (descripton: %s) from machine %s",
|
||||
snapshotName, snapshotDesc, machine.getName());
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
logger.error(e, "Problem creating snapshot %s (descripton: %s) from machine %s", snapshotName,
|
||||
snapshotDesc, machine.getName());
|
||||
throw Throwables.propagate(e);
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.unlockMachine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return machine.getCurrentSnapshot();
|
||||
|
|
|
@ -19,35 +19,49 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions.admin;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
* Sets up jetty so that it can serve the preseed.cfg file to automate master creation.
|
||||
*
|
||||
* TODO - Probably we can make this only start jetty. This has not been used to serve isos.
|
||||
*
|
||||
* @author Andrea Turli, David Alves
|
||||
*/
|
||||
@Singleton
|
||||
public class StartJettyIfNotAlreadyRunning extends CacheLoader<IsoSpec, URI> {
|
||||
|
||||
@Resource
|
||||
@javax.annotation.Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
private Server jetty;
|
||||
|
@ -60,7 +74,7 @@ public class StartJettyIfNotAlreadyRunning extends CacheLoader<IsoSpec, URI> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public URI load(IsoSpec isoSpec) throws Exception {
|
||||
public URI load(IsoSpec isoSpec) throws Exception {
|
||||
try {
|
||||
start();
|
||||
} catch (Exception e) {
|
||||
|
@ -74,24 +88,36 @@ public class StartJettyIfNotAlreadyRunning extends CacheLoader<IsoSpec, URI> {
|
|||
if (jetty.getState().equals(Server.STARTED)) {
|
||||
logger.debug("not starting jetty, as existing host is serving %s", preconfigurationUrl);
|
||||
} else {
|
||||
logger.debug(">> starting jetty to serve %s", preconfigurationUrl);
|
||||
ResourceHandler resourceHandler = new ResourceHandler();
|
||||
resourceHandler.setDirectoriesListed(true);
|
||||
resourceHandler.setWelcomeFiles(new String[]{"index.html"});
|
||||
|
||||
resourceHandler.setResourceBase("");
|
||||
HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[]{resourceHandler, new DefaultHandler()});
|
||||
jetty.setHandler(handlers);
|
||||
|
||||
try {
|
||||
|
||||
// find the the parent dir inside the jar to serve the file from
|
||||
|
||||
final String preseedFile = IOUtils
|
||||
.toString(Resource.newSystemResource("preseed.cfg").getURL().openStream());
|
||||
|
||||
checkState(preseedFile != null);
|
||||
|
||||
// since we're only serving the preseed.cfg file respond to all requests with it
|
||||
jetty.setHandler(new AbstractHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request,
|
||||
HttpServletResponse response) throws IOException, ServletException {
|
||||
response.setContentType("text/plain;charset=utf-8");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
baseRequest.setHandled(true);
|
||||
response.getWriter().println(preseedFile);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jetty.start();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "Server jetty could not be started for %s", preconfigurationUrl);
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
logger.debug("<< serving %s", resourceHandler.getBaseResource());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PreDestroy()
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -58,8 +59,8 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
|
|||
private final RetryIfSocketNotYetOpen socketTester;
|
||||
private final Supplier<NodeMetadata> host;
|
||||
private final Supplier<URI> providerSupplier;
|
||||
private final String identity;
|
||||
private final String credential;
|
||||
// private final String identity;
|
||||
// private final String credential;
|
||||
private final Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode;
|
||||
private transient VirtualBoxManager manager;
|
||||
|
||||
|
@ -67,14 +68,15 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
|
|||
@Inject
|
||||
public StartVBoxIfNotAlreadyRunning(Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode,
|
||||
Factory runScriptOnNodeFactory, RetryIfSocketNotYetOpen socketTester, Supplier<NodeMetadata> host,
|
||||
@Provider Supplier<URI> providerSupplier, @Identity String identity, @Credential String credential) {
|
||||
@Provider Supplier<URI> providerSupplier, @Nullable @Identity String identity,
|
||||
@Nullable @Credential String credential) {
|
||||
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
|
||||
this.socketTester = checkNotNull(socketTester, "socketTester");
|
||||
this.socketTester.seconds(3L);
|
||||
this.host = checkNotNull(host, "host");
|
||||
this.providerSupplier = checkNotNull(providerSupplier, "endpoint to virtualbox websrvd is needed");
|
||||
this.identity = checkNotNull(identity, "identity");
|
||||
this.credential = checkNotNull(credential, "credential");
|
||||
// this.identity = checkNotNull(identity, "identity");
|
||||
// this.credential = checkNotNull(credential, "credential");
|
||||
this.managerForNode = checkNotNull(managerForNode, "managerForNode");
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,7 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
|
|||
}
|
||||
}
|
||||
manager = managerForNode.apply(host);
|
||||
manager.connect(provider.toASCIIString(), identity, credential);
|
||||
manager.connect(provider.toASCIIString(), "", "");
|
||||
if (logger.isDebugEnabled())
|
||||
if (manager.getSessionObject().getState() != SessionState.Unlocked)
|
||||
logger.warn("manager is not in unlocked state " + manager.getSessionObject().getState());
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* 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.virtualbox.statements;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Deletes /etc/gshadow.lock. see https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/732864.
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
public class DeleteGShadowLock implements Statement {
|
||||
|
||||
@Override
|
||||
public Iterable<String> functionDependencies(OsFamily family) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(OsFamily family) {
|
||||
if (checkNotNull(family, "family") == OsFamily.WINDOWS)
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
return "rm -f /etc/passwd.lock /etc/group.lock /etc/gshadow.lock";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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.virtualbox;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests that jetty is able to serve the preseed.cfg file. This test is here to have access to the
|
||||
* defaultProperties() method in {@link VirtualBoxPropertiesBuilder}.
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "StartJettyIfNotAlreadyRunningLiveTest")
|
||||
public class StartJettyIfNotAlreadyRunningLiveTest {
|
||||
|
||||
@Test
|
||||
public void testJettyServerServesPreseedFile() throws Exception {
|
||||
Properties props = new VirtualBoxPropertiesBuilder().defaultProperties();
|
||||
|
||||
String preconfigurationUrl = props.getProperty(VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL);
|
||||
|
||||
int port = URI.create(preconfigurationUrl).getPort();
|
||||
|
||||
Server server = new Server(port);
|
||||
|
||||
StartJettyIfNotAlreadyRunning starter = new StartJettyIfNotAlreadyRunning(preconfigurationUrl, server);
|
||||
|
||||
starter.load(null);
|
||||
|
||||
String preseedFileFromJetty = IOUtils.toString(new URL("http://127.0.0.1:" + port + "/preseed.cfg").openStream());
|
||||
String preseedFileFromFile = IOUtils
|
||||
.toString(this.getClass().getClassLoader().getResourceAsStream("preseed.cfg")) + "\n";
|
||||
assertEquals(preseedFileFromFile, preseedFileFromJetty);
|
||||
}
|
||||
}
|
|
@ -31,9 +31,11 @@ import org.jclouds.compute.ComputeServiceContextFactory;
|
|||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
@ -58,7 +60,7 @@ public class VirtualBoxExperimentLiveTest {
|
|||
|
||||
@BeforeClass
|
||||
public void setUp() {
|
||||
context = new ComputeServiceContextFactory().createContext("virtualbox", "toor", "password",
|
||||
context = new ComputeServiceContextFactory().createContext("virtualbox", "", "",
|
||||
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule()));
|
||||
}
|
||||
|
||||
|
@ -66,7 +68,8 @@ public class VirtualBoxExperimentLiveTest {
|
|||
public void testLaunchCluster() throws RunNodesException {
|
||||
int numNodes = 4;
|
||||
final String clusterName = "test-launch-cluster";
|
||||
Set<? extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup(clusterName, numNodes);
|
||||
Set<? extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup(clusterName, numNodes,
|
||||
TemplateOptions.Builder.runScript(AdminAccess.standard()));
|
||||
assertEquals(numNodes, nodes.size(), "wrong number of nodes");
|
||||
for (NodeMetadata node : nodes) {
|
||||
logger.debug("Created Node: %s", node);
|
||||
|
|
Loading…
Reference in New Issue