fixed base computeservice test; fixed logging in runScript; fixed terremark to not use the unstable jeos and work around service unauthorized problems

This commit is contained in:
Adrian Cole 2010-05-03 11:40:27 -07:00
parent 98cae35ec6
commit b432bbbe8c
12 changed files with 178 additions and 14 deletions

View File

@ -66,8 +66,8 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
protected final ExecutorService executor; protected final ExecutorService executor;
@Inject @Inject
protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(AddNodeWithTagStrategy addNodeWithTagStrategy, protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(
ListNodesStrategy listNodesStrategy, AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils, @Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
this.addNodeWithTagStrategy = addNodeWithTagStrategy; this.addNodeWithTagStrategy = addNodeWithTagStrategy;
@ -98,6 +98,8 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
logger.debug("<< options applied node(%s)", node.getId()); logger.debug("<< options applied node(%s)", node.getId());
nodes.add(node); nodes.add(node);
} catch (Exception e) { } catch (Exception e) {
logger.error(e, "<< error applying options (%s) on node (%s)", template
.getOptions(), node.getId());
if (!template.getOptions().shouldDestroyOnError()) if (!template.getOptions().shouldDestroyOnError())
nodes.add(node); nodes.add(node);
} }

View File

@ -144,7 +144,7 @@ public class ComputeUtils {
if (passed) if (passed)
logger.debug("<< port %s:%d opened", inetAddress, port); logger.debug("<< port %s:%d opened", inetAddress, port);
else else
logger.warn("<< port %s:%d didn't open after %d seconds", seconds, inetAddress, port); logger.warn("<< port %s:%d didn't open after %d seconds", inetAddress, port, seconds);
} }
public InstallRSAPrivateKey installKeyOnNode(NodeMetadata node, String privateKey) { public InstallRSAPrivateKey installKeyOnNode(NodeMetadata node, String privateKey) {

View File

@ -214,7 +214,7 @@ public abstract class BaseComputeServiceLiveTest {
.values()); .values());
checkNodes(nodes, tag); checkNodes(nodes, tag);
NodeMetadata node = nodes.first(); NodeMetadata node = nodes.first();
this.nodes.add(node);
assertEquals(nodes.size(), 1); assertEquals(nodes.size(), 1);
assertLocationSameOrChild(node.getLocation(), template.getLocation()); assertLocationSameOrChild(node.getLocation(), template.getLocation());
assertEquals(node.getImage(), template.getImage()); assertEquals(node.getImage(), template.getImage());
@ -224,7 +224,7 @@ public abstract class BaseComputeServiceLiveTest {
public void testScriptExecutionAfterBootWithBasicTemplate() throws Exception { public void testScriptExecutionAfterBootWithBasicTemplate() throws Exception {
String tag = this.tag + "run"; String tag = this.tag + "run";
Template simpleTemplate = buildTemplate(client.templateBuilder()); Template simpleTemplate = buildTemplate(client.templateBuilder());
simpleTemplate.getOptions().blockOnPort(22, 60); simpleTemplate.getOptions().blockOnPort(22, 120);
try { try {
Map<String, ? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, simpleTemplate); Map<String, ? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, simpleTemplate);
Credentials good = nodes.values().iterator().next().getCredentials(); Credentials good = nodes.values().iterator().next().getCredentials();
@ -254,7 +254,7 @@ public abstract class BaseComputeServiceLiveTest {
RunScriptOptions.Builder.overrideCredentialsWith(creds)); RunScriptOptions.Builder.overrideCredentialsWith(creds));
} catch (SshException e) { } catch (SshException e) {
if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) { if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) {
System.err.printf("bad credentials: %s:%s for %s", creds.account, creds.key, client System.err.printf("bad credentials: %s:%s for %s%n", creds.account, creds.key, client
.getNodesWithTag(tag)); .getNodesWithTag(tag));
} }
throw e; throw e;
@ -370,12 +370,14 @@ public abstract class BaseComputeServiceLiveTest {
assert node.getValue() instanceof NodeMetadata; assert node.getValue() instanceof NodeMetadata;
NodeMetadata nodeMetadata = (NodeMetadata) node.getValue(); NodeMetadata nodeMetadata = (NodeMetadata) node.getValue();
assert nodeMetadata.getId() != null : nodeMetadata; assert nodeMetadata.getId() != null : nodeMetadata;
assert nodeMetadata.getImage() != null : node; // nullable
// assert nodeMetadata.getImage() != null : node;
// user specified name is not always supported // user specified name is not always supported
// assert nodeMetadata.getName() != null : nodeMetadata; // assert nodeMetadata.getName() != null : nodeMetadata;
if (nodeMetadata.getState() != NodeState.TERMINATED) { if (nodeMetadata.getState() != NodeState.TERMINATED) {
assert nodeMetadata.getPublicAddresses() != null : nodeMetadata; assert nodeMetadata.getPublicAddresses() != null : nodeMetadata;
assert nodeMetadata.getPublicAddresses().size() > 0 : nodeMetadata; assert nodeMetadata.getPublicAddresses().size() > 0
|| nodeMetadata.getPrivateAddresses().size() > 0 : nodeMetadata;
assertNotNull(nodeMetadata.getPrivateAddresses()); assertNotNull(nodeMetadata.getPrivateAddresses());
} }
} }

View File

@ -205,7 +205,6 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
InstantiateVAppTemplateOptions options = processorCount( InstantiateVAppTemplateOptions options = processorCount(
Double.valueOf(template.getSize().getCores()).intValue()).memory( Double.valueOf(template.getSize().getCores()).intValue()).memory(
template.getSize().getRam()).disk(template.getSize().getDisk() * 1024 * 1024l); template.getSize().getRam()).disk(template.getSize().getDisk() * 1024 * 1024l);
Map<String, String> metaMap = computeClient.start(template.getLocation().getId(), name, Map<String, String> metaMap = computeClient.start(template.getLocation().getId(), name,
template.getImage().getId(), options, template.getOptions().getInboundPorts()); template.getImage().getId(), options, template.getOptions().getInboundPorts());
VApp vApp = client.getVApp(metaMap.get("id")); VApp vApp = client.getVApp(metaMap.get("id"));

View File

@ -44,7 +44,11 @@ import javax.inject.Singleton;
import org.jclouds.concurrent.ExpirableSupplier; import org.jclouds.concurrent.ExpirableSupplier;
import org.jclouds.concurrent.internal.SyncProxy; import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.encryption.EncryptionService; import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.predicates.AddressReachable; import org.jclouds.predicates.AddressReachable;
@ -69,6 +73,7 @@ import org.jclouds.vcloud.endpoints.VDC;
import org.jclouds.vcloud.endpoints.internal.CatalogItemRoot; import org.jclouds.vcloud.endpoints.internal.CatalogItemRoot;
import org.jclouds.vcloud.endpoints.internal.VAppRoot; import org.jclouds.vcloud.endpoints.internal.VAppRoot;
import org.jclouds.vcloud.endpoints.internal.VAppTemplateRoot; import org.jclouds.vcloud.endpoints.internal.VAppTemplateRoot;
import org.jclouds.vcloud.handlers.ParseVCloudErrorFromHttpResponse;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient; import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
@ -121,6 +126,7 @@ public class VCloudRestClientModule extends AbstractModule {
@Override @Override
protected void configure() { protected void configure() {
requestInjection(this); requestInjection(this);
bindErrorHandlers();
} }
@VCloudToken @VCloudToken
@ -280,6 +286,15 @@ public class VCloudRestClientModule extends AbstractModule {
return network.toASCIIString(); return network.toASCIIString();
} }
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
ParseVCloudErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
ParseVCloudErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
ParseVCloudErrorFromHttpResponse.class);
}
@Provides @Provides
@TasksList @TasksList
@Singleton @Singleton

View File

@ -0,0 +1,91 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.vcloud.handlers;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.Logger;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Utils;
import com.google.common.io.Closeables;
/**
* This will parse and set an appropriate exception on the command object.
*
* @author Adrian Cole
*
*/
public class ParseVCloudErrorFromHttpResponse implements HttpErrorHandler {
@Resource
protected Logger logger = Logger.NULL;
public static final Pattern RESOURCE_PATTERN = Pattern
.compile(".*/v[^/]*/[0-9]+/([^/]+)/([0-9]+)");
public void handleError(HttpCommand command, HttpResponse response) {
Exception exception = new HttpResponseException(command, response);
try {
String content = parseErrorFromContentOrNull(command, response);
switch (response.getStatusCode()) {
case 401:
exception = new AuthorizationException(command.getRequest(), content);
break;
case 404:
if (!command.getRequest().getMethod().equals("DELETE")) {
String path = command.getRequest().getEndpoint().getPath();
Matcher matcher = RESOURCE_PATTERN.matcher(path);
String message;
if (matcher.find()) {
message = String.format("%s %s not found", matcher.group(1), matcher.group(2));
} else {
message = path;
}
exception = new ResourceNotFoundException(message);
}
break;
default:
exception = new HttpResponseException(command, response, content);
}
} finally {
Closeables.closeQuietly(response.getContent());
command.setException(exception);
}
}
String parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) {
if (response.getContent() != null) {
try {
return Utils.toStringAndClose(response.getContent());
} catch (IOException e) {
logger.warn(e, "exception reading error from response", response);
}
}
return null;
}
}

View File

@ -37,12 +37,12 @@ import javax.ws.rs.core.UriBuilder;
import org.jboss.resteasy.specimpl.UriBuilderImpl; import org.jboss.resteasy.specimpl.UriBuilderImpl;
import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.functions.config.ParserModule; import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.http.handlers.CloseContentAndSetExceptionErrorHandler;
import org.jclouds.http.handlers.DelegatingErrorHandler; import org.jclouds.http.handlers.DelegatingErrorHandler;
import org.jclouds.http.handlers.DelegatingRetryHandler; import org.jclouds.http.handlers.DelegatingRetryHandler;
import org.jclouds.http.handlers.RedirectionRetryHandler; import org.jclouds.http.handlers.RedirectionRetryHandler;
import org.jclouds.util.Jsr330; import org.jclouds.util.Jsr330;
import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.handlers.ParseVCloudErrorFromHttpResponse;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -142,14 +142,14 @@ public class VCloudRestClientModuleTest {
void testServerErrorHandler() { void testServerErrorHandler() {
DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class); DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
assertEquals(handler.getServerErrorHandler().getClass(), assertEquals(handler.getServerErrorHandler().getClass(),
CloseContentAndSetExceptionErrorHandler.class); ParseVCloudErrorFromHttpResponse.class);
} }
@Test @Test
void testClientErrorHandler() { void testClientErrorHandler() {
DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class); DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
assertEquals(handler.getClientErrorHandler().getClass(), assertEquals(handler.getClientErrorHandler().getClass(),
CloseContentAndSetExceptionErrorHandler.class); ParseVCloudErrorFromHttpResponse.class);
} }
@Test @Test

View File

@ -73,6 +73,7 @@ import org.jclouds.vcloud.terremark.domain.Protocol;
import org.jclouds.vcloud.terremark.domain.PublicIpAddress; import org.jclouds.vcloud.terremark.domain.PublicIpAddress;
import org.jclouds.vcloud.terremark.domain.VAppConfiguration; import org.jclouds.vcloud.terremark.domain.VAppConfiguration;
import org.jclouds.vcloud.terremark.functions.ParseTaskFromLocationHeader; import org.jclouds.vcloud.terremark.functions.ParseTaskFromLocationHeader;
import org.jclouds.vcloud.terremark.functions.ReturnEmptySetOnUnauthorized;
import org.jclouds.vcloud.terremark.functions.ReturnVoidOnDeleteDefaultIp; import org.jclouds.vcloud.terremark.functions.ReturnVoidOnDeleteDefaultIp;
import org.jclouds.vcloud.terremark.options.AddInternetServiceOptions; import org.jclouds.vcloud.terremark.options.AddInternetServiceOptions;
import org.jclouds.vcloud.terremark.options.AddNodeOptions; import org.jclouds.vcloud.terremark.options.AddNodeOptions;
@ -290,6 +291,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class) @Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/internetServices/{internetServiceId}/nodes") @Path("/internetServices/{internetServiceId}/nodes")
@XMLResponseParser(NodesHandler.class) @XMLResponseParser(NodesHandler.class)
@ExceptionParser(ReturnEmptySetOnUnauthorized.class)
@Consumes(APPLICATION_XML) @Consumes(APPLICATION_XML)
ListenableFuture<? extends SortedSet<Node>> getNodes( ListenableFuture<? extends SortedSet<Node>> getNodes(
@PathParam("internetServiceId") int internetServiceId); @PathParam("internetServiceId") int internetServiceId);

View File

@ -94,7 +94,7 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
@Override @Override
protected TemplateBuilder provideTemplate(TemplateBuilderImpl template) { protected TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
return template.imageNameMatches(".*JeOS.*"); return template.osFamily(OsFamily.UBUNTU);
} }
private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize(); private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize();

View File

@ -0,0 +1,49 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.vcloud.terremark.functions;
import static org.jclouds.util.Utils.propagateOrNull;
import java.util.SortedSet;
import javax.inject.Singleton;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.vcloud.terremark.domain.Node;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSortedSet;
/**
* There's a bug where calling get after delete throws an unauthorized exception.
* <p/>
* https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60/p/264/876.aspx#876
*
* @author Adrian Cole
*/
@Singleton
public class ReturnEmptySetOnUnauthorized implements Function<Exception, SortedSet<Node>> {
@SuppressWarnings("unchecked")
public SortedSet<Node> apply(Exception from) {
if (from instanceof AuthorizationException) {
return ImmutableSortedSet.<Node> of();
}
return SortedSet.class.cast(propagateOrNull(from));
}
}

View File

@ -25,6 +25,7 @@ import java.util.regex.Pattern;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -45,6 +46,8 @@ public class ReturnVoidOnDeleteDefaultIp implements Function<Exception, Void> {
if (hre.getResponse().getStatusCode() == 503 || hre.getResponse().getStatusCode() == 401 if (hre.getResponse().getStatusCode() == 503 || hre.getResponse().getStatusCode() == 401
|| MESSAGE_PATTERN.matcher(hre.getMessage()).matches()) || MESSAGE_PATTERN.matcher(hre.getMessage()).matches())
return null; return null;
} else if (from instanceof AuthorizationException) {
return null;
} }
return Void.class.cast(propagateOrNull(from)); return Void.class.cast(propagateOrNull(from));
} }

View File

@ -56,6 +56,7 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import org.jclouds.vcloud.terremark.domain.InternetServiceConfiguration; import org.jclouds.vcloud.terremark.domain.InternetServiceConfiguration;
import org.jclouds.vcloud.terremark.domain.NodeConfiguration; import org.jclouds.vcloud.terremark.domain.NodeConfiguration;
import org.jclouds.vcloud.terremark.domain.Protocol; import org.jclouds.vcloud.terremark.domain.Protocol;
import org.jclouds.vcloud.terremark.functions.ReturnEmptySetOnUnauthorized;
import org.jclouds.vcloud.terremark.options.AddInternetServiceOptions; import org.jclouds.vcloud.terremark.options.AddInternetServiceOptions;
import org.jclouds.vcloud.terremark.options.AddNodeOptions; import org.jclouds.vcloud.terremark.options.AddNodeOptions;
import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions; import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions;
@ -444,7 +445,7 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
assertResponseParserClassEquals(method, httpMethod, ParseSax.class); assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodesHandler.class); assertSaxResponseParserClassEquals(method, NodesHandler.class);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, ReturnEmptySetOnUnauthorized.class);
checkFilters(httpMethod); checkFilters(httpMethod);
} }