mirror of https://github.com/apache/jclouds.git
updated gae demo to demonstrate use of views and GAE ThreadFactory
This commit is contained in:
parent
7854d85f13
commit
a2c8993592
|
@ -40,8 +40,6 @@
|
||||||
<appengine.sdk.version>1.6.5</appengine.sdk.version>
|
<appengine.sdk.version>1.6.5</appengine.sdk.version>
|
||||||
<devappserver.address>localhost</devappserver.address>
|
<devappserver.address>localhost</devappserver.address>
|
||||||
<devappserver.port>8088</devappserver.port>
|
<devappserver.port>8088</devappserver.port>
|
||||||
<test.hpcloud.identity>FIXME_IDENTITY</test.hpcloud.identity>
|
|
||||||
<test.hpcloud.credential>FIXME_CREDENTIAL</test.hpcloud.credential>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -57,13 +55,13 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds.provider</groupId>
|
<groupId>org.jclouds.provider</groupId>
|
||||||
<artifactId>hpcloud-objectstorage</artifactId>
|
<artifactId>aws-s3</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds.provider</groupId>
|
<groupId>org.jclouds.provider</groupId>
|
||||||
<artifactId>hpcloud-compute</artifactId>
|
<artifactId>hpcloud-objectstorage</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -369,8 +367,12 @@
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemPropertyVariables>
|
<systemPropertyVariables>
|
||||||
<test.hpcloud.identity>${test.hpcloud.identity}</test.hpcloud.identity>
|
<!-- note you can add support for new clouds by adding more entries here
|
||||||
<test.hpcloud.credential>${test.hpcloud.credential}</test.hpcloud.credential>
|
after adding maven dependency -->
|
||||||
|
<test.aws-s3.identity>${test.aws-s3.identity}</test.aws-s3.identity>
|
||||||
|
<test.aws-s3.credential>${test.aws-s3.credential}</test.aws-s3.credential>
|
||||||
|
<test.hpcloud-objectstorage.identity>${test.hpcloud-objectstorage.identity}</test.hpcloud-objectstorage.identity>
|
||||||
|
<test.hpcloud-objectstorage.credential>${test.hpcloud-objectstorage.credential}</test.hpcloud-objectstorage.credential>
|
||||||
<appengine.sdk.root>${appengine.sdk.root}</appengine.sdk.root>
|
<appengine.sdk.root>${appengine.sdk.root}</appengine.sdk.root>
|
||||||
<devappserver.address>${devappserver.address}</devappserver.address>
|
<devappserver.address>${devappserver.address}</devappserver.address>
|
||||||
<devappserver.port>${devappserver.port}</devappserver.port>
|
<devappserver.port>${devappserver.port}</devappserver.port>
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
/**
|
||||||
|
* 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.samples.googleappengine;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Iterables.concat;
|
||||||
|
import static com.google.common.collect.Iterables.size;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.jclouds.View;
|
||||||
|
import org.jclouds.domain.ResourceMetadata;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.samples.googleappengine.domain.ResourceResult;
|
||||||
|
import org.jclouds.samples.googleappengine.functions.ResourceMetadataToResourceResult;
|
||||||
|
import org.jclouds.samples.googleappengine.functions.ViewToAsyncResources;
|
||||||
|
import org.jclouds.samples.googleappengine.functions.ViewToId;
|
||||||
|
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows an example of how to list all resources from all views!
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class GetAllResourcesController extends HttpServlet {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final ListeningExecutorService currentRequestExecutorService;
|
||||||
|
private final Iterable<View> views;
|
||||||
|
private final ViewToAsyncResources viewToAsyncResources;
|
||||||
|
private final ResourceMetadataToResourceResult resourceMetadataToStatusResult;
|
||||||
|
private final Provider<Long> remainingMillis;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GetAllResourcesController(ListeningExecutorService currentRequestExecutorService, Iterable<View> views,
|
||||||
|
ViewToAsyncResources viewToAsyncResources, ResourceMetadataToResourceResult resourceMetadataToStatusResult,
|
||||||
|
Provider<Long> remainingMillis) {
|
||||||
|
this.currentRequestExecutorService = currentRequestExecutorService;
|
||||||
|
this.views = views;
|
||||||
|
this.viewToAsyncResources = viewToAsyncResources;
|
||||||
|
this.resourceMetadataToStatusResult = resourceMetadataToStatusResult;
|
||||||
|
this.remainingMillis = remainingMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
try {
|
||||||
|
addResourcesToRequest(request);
|
||||||
|
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/resources.jsp");
|
||||||
|
dispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e, "Error listing resources");
|
||||||
|
throw new ServletException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addResourcesToRequest(HttpServletRequest request) {
|
||||||
|
Stopwatch watch = new Stopwatch().start();
|
||||||
|
logger.info("ready to list views: %s", transform(views, ViewToId.INSTANCE));
|
||||||
|
Iterable<ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> asyncResources = transform(views,
|
||||||
|
viewToAsyncResources);
|
||||||
|
logger.info("launched %s tasks with %sms remaining", size(asyncResources), remainingMillis.get());
|
||||||
|
|
||||||
|
Set<Iterable<? extends ResourceMetadata<?>>> done = allResourcesWithinDeadline(asyncResources);
|
||||||
|
logger.info("%s tasks completed in %sms with %sms remaining", size(done), watch.stop().elapsedMillis(),
|
||||||
|
remainingMillis.get());
|
||||||
|
|
||||||
|
Iterable<ResourceMetadata<?>> flattened = concat(done);
|
||||||
|
|
||||||
|
Set<ResourceResult> results = FluentIterable.from(flattened).transform(resourceMetadataToStatusResult)
|
||||||
|
.toImmutableSet();
|
||||||
|
|
||||||
|
request.setAttribute("resources", results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Iterable<? extends ResourceMetadata<?>>> allResourcesWithinDeadline(
|
||||||
|
Iterable<ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> asyncResources) {
|
||||||
|
Builder<Iterable<? extends ResourceMetadata<?>>> resourcesWeCanList = addToBuilderOnComplete(asyncResources);
|
||||||
|
|
||||||
|
// only serve resources that made it by the timeout
|
||||||
|
blockUntilAllDoneOrCancelOnTimeout(asyncResources);
|
||||||
|
|
||||||
|
return resourcesWeCanList.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder<Iterable<? extends ResourceMetadata<?>>> addToBuilderOnComplete(
|
||||||
|
Iterable<ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> asyncResources) {
|
||||||
|
|
||||||
|
final Builder<Iterable<? extends ResourceMetadata<?>>> resourcesWeCanList = ImmutableSet
|
||||||
|
.<Iterable<? extends ResourceMetadata<?>>> builder();
|
||||||
|
|
||||||
|
for (final ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>> asyncResource : asyncResources) {
|
||||||
|
Futures.addCallback(asyncResource, new FutureCallback<Iterable<? extends ResourceMetadata<?>>>() {
|
||||||
|
public void onSuccess(Iterable<? extends ResourceMetadata<?>> result) {
|
||||||
|
if (result != null)
|
||||||
|
resourcesWeCanList.add(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
if (!(t instanceof CancellationException))
|
||||||
|
logger.info("exception getting resource %s: %s", asyncResource, t.getMessage());
|
||||||
|
}
|
||||||
|
}, currentRequestExecutorService);
|
||||||
|
|
||||||
|
}
|
||||||
|
return resourcesWeCanList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void blockUntilAllDoneOrCancelOnTimeout(
|
||||||
|
Iterable<ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> asyncResources) {
|
||||||
|
List<ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> remaining = Lists
|
||||||
|
.newArrayList(asyncResources);
|
||||||
|
|
||||||
|
while (remaining.size() > 0) {
|
||||||
|
ListenableFuture<?> resource = remaining.remove(0);
|
||||||
|
if (remainingMillis.get() <= 0) {
|
||||||
|
if (!resource.isDone())
|
||||||
|
resource.cancel(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
resource.get(remainingMillis.get(), TimeUnit.MILLISECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.info("exception getting resource %s: %s", resource, e.getMessage());
|
||||||
|
if (!resource.isDone())
|
||||||
|
resource.cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,93 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.samples.googleappengine;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.servlet.RequestDispatcher;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.samples.googleappengine.functions.BlobStoreContextToStatusResult;
|
|
||||||
import org.jclouds.samples.googleappengine.functions.ComputeServiceContextToStatusResult;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows an example of how to use {@link BlobStoreContext} and {@link ComputeServiceContext}
|
|
||||||
* injected with Guice.
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class GetAllStatusController extends HttpServlet {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final Iterable<BlobStoreContext> blobsStoreContexts;
|
|
||||||
private final Iterable<ComputeServiceContext> computeServiceContexts;
|
|
||||||
private final BlobStoreContextToStatusResult blobStoreContextToContainerResult;
|
|
||||||
private final ComputeServiceContextToStatusResult computeServiceContextToContainerResult;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
GetAllStatusController(Iterable<BlobStoreContext> blobsStoreContexts,
|
|
||||||
Iterable<ComputeServiceContext> computeServiceContexts,
|
|
||||||
BlobStoreContextToStatusResult blobStoreContextToContainerResult,
|
|
||||||
ComputeServiceContextToStatusResult computeServiceContextToContainerResult) {
|
|
||||||
this.blobsStoreContexts = blobsStoreContexts;
|
|
||||||
this.computeServiceContexts = computeServiceContexts;
|
|
||||||
this.blobStoreContextToContainerResult = blobStoreContextToContainerResult;
|
|
||||||
this.computeServiceContextToContainerResult = computeServiceContextToContainerResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
try {
|
|
||||||
addStatusResultsToRequest(request);
|
|
||||||
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/status.jsp");
|
|
||||||
dispatcher.forward(request, response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e, "Error listing status");
|
|
||||||
throw new ServletException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addStatusResultsToRequest(HttpServletRequest request) throws InterruptedException, ExecutionException,
|
|
||||||
TimeoutException {
|
|
||||||
request.setAttribute(
|
|
||||||
"status",
|
|
||||||
ImmutableSet.copyOf(Iterables.concat(
|
|
||||||
Iterables.transform(blobsStoreContexts, blobStoreContextToContainerResult),
|
|
||||||
Iterables.transform(computeServiceContexts, computeServiceContextToContainerResult))));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -18,6 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.samples.googleappengine.config;
|
package org.jclouds.samples.googleappengine.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static com.google.common.collect.Iterables.get;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
import static com.google.common.io.Closeables.closeQuietly;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
|
||||||
|
@ -26,59 +31,90 @@ import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
import org.jclouds.ContextBuilder;
|
import org.jclouds.ContextBuilder;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.View;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
|
||||||
import org.jclouds.gae.config.AsyncGoogleAppEngineConfigurationModule;
|
import org.jclouds.gae.config.AsyncGoogleAppEngineConfigurationModule;
|
||||||
import org.jclouds.samples.googleappengine.GetAllStatusController;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
|
import org.jclouds.providers.Providers;
|
||||||
|
import org.jclouds.samples.googleappengine.GetAllResourcesController;
|
||||||
|
|
||||||
|
import com.google.appengine.api.ThreadManager;
|
||||||
|
import com.google.apphosting.api.ApiProxy;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.servlet.GuiceServletContextListener;
|
import com.google.inject.servlet.GuiceServletContextListener;
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup Logging and create {@link Injector} for use in testing Amazon EC2 and S3.
|
* Setup Logging and create {@link Injector} for use in testing Views
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class GuiceServletConfig extends GuiceServletContextListener {
|
public class GuiceServletConfig extends GuiceServletContextListener {
|
||||||
|
|
||||||
private Iterable<BlobStoreContext> blobsStoreContexts;
|
private Iterable<View> views;
|
||||||
private Iterable<ComputeServiceContext> computeServiceContexts;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
Properties overrides = loadJCloudsProperties(servletContextEvent);
|
final Properties overrides = loadJCloudsProperties(servletContextEvent);
|
||||||
|
// until there's a global skip image parse option
|
||||||
|
overrides.setProperty("jclouds.ec2.ami-query", "");
|
||||||
|
overrides.setProperty("jclouds.ec2.cc-ami-query", "");
|
||||||
|
|
||||||
|
// ensure requests don't take longer than GAE timeout
|
||||||
overrides.setProperty(TIMEOUT_NODE_TERMINATED, "25000");
|
overrides.setProperty(TIMEOUT_NODE_TERMINATED, "25000");
|
||||||
overrides.setProperty(TIMEOUT_NODE_RUNNING, "25000");
|
overrides.setProperty(TIMEOUT_NODE_RUNNING, "25000");
|
||||||
overrides.setProperty(TIMEOUT_SCRIPT_COMPLETE, "25000");
|
overrides.setProperty(TIMEOUT_SCRIPT_COMPLETE, "25000");
|
||||||
overrides.setProperty(TIMEOUT_PORT_OPEN, "25000");
|
overrides.setProperty(TIMEOUT_PORT_OPEN, "25000");
|
||||||
|
|
||||||
// note that this module hooks into the async urlfetchservice
|
// correct the classloader so that extensions can be found
|
||||||
ImmutableSet<Module> modules = ImmutableSet.<Module> of(new AsyncGoogleAppEngineConfigurationModule());
|
Thread.currentThread().setContextClassLoader(Providers.class.getClassLoader());
|
||||||
|
|
||||||
blobsStoreContexts = ImmutableSet.of(
|
Iterable<ProviderMetadata> identityInProperties = providersWeHaveIdentitiesFor(overrides);
|
||||||
ContextBuilder.newBuilder("hpcloud-objectstorage")
|
|
||||||
.modules(modules)
|
final ImmutableSet<Module> modules = ImmutableSet.<Module> of(new AsyncGoogleAppEngineConfigurationModule());
|
||||||
.overrides(overrides)
|
views = transform(identityInProperties, new Function<ProviderMetadata, View>() {
|
||||||
.buildView(BlobStoreContext.class));
|
|
||||||
computeServiceContexts = ImmutableSet.of(
|
@Override
|
||||||
ContextBuilder.newBuilder("hpcloud-compute")
|
public View apply(ProviderMetadata input) {
|
||||||
.modules(modules)
|
TypeToken<? extends View> defaultView = get(input.getApiMetadata().getViews(), 0);
|
||||||
.overrides(overrides)
|
return ContextBuilder.newBuilder(input).modules(modules).overrides(overrides).buildView(defaultView);
|
||||||
.buildView(ComputeServiceContext.class));
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
super.contextInitialized(servletContextEvent);
|
super.contextInitialized(servletContextEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Iterable<ProviderMetadata> providersWeHaveIdentitiesFor(final Properties overrides) {
|
||||||
|
// there's a chance serviceloader is being lazy, and we don't want
|
||||||
|
// ConcurrentModificationException, so copy into a set.
|
||||||
|
return ImmutableSet.copyOf(filter(Providers.all(), new Predicate<ProviderMetadata>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(ProviderMetadata input) {
|
||||||
|
return overrides.containsKey(input.getId() + ".identity");
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
private Properties loadJCloudsProperties(ServletContextEvent servletContextEvent) {
|
private Properties loadJCloudsProperties(ServletContextEvent servletContextEvent) {
|
||||||
InputStream input = servletContextEvent.getServletContext().getResourceAsStream("/WEB-INF/jclouds.properties");
|
InputStream input = servletContextEvent.getServletContext().getResourceAsStream("/WEB-INF/jclouds.properties");
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
|
@ -87,35 +123,44 @@ public class GuiceServletConfig extends GuiceServletContextListener {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} finally {
|
} finally {
|
||||||
Closeables.closeQuietly(input);
|
closeQuietly(input);
|
||||||
}
|
}
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Injector getInjector() {
|
protected Injector getInjector() {
|
||||||
return Guice.createInjector(new ServletModule() {
|
return Guice.createInjector(new JDKLoggingModule(), new ServletModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
bind(new TypeLiteral<Iterable<BlobStoreContext>>() {
|
bind(new TypeLiteral<Iterable<View>>() {
|
||||||
}).toInstance(GuiceServletConfig.this.blobsStoreContexts);
|
}).toInstance(GuiceServletConfig.this.views);
|
||||||
bind(new TypeLiteral<Iterable<ComputeServiceContext>>() {
|
serve("*.check").with(GetAllResourcesController.class);
|
||||||
}).toInstance(GuiceServletConfig.this.computeServiceContexts);
|
|
||||||
serve("*.check").with(GetAllStatusController.class);
|
|
||||||
requestInjection(this);
|
requestInjection(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
);
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
long remainingMillis() {
|
||||||
|
// leave 100ms for any post processing
|
||||||
|
return ApiProxy.getCurrentEnvironment().getRemainingMillis() - 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ListeningExecutorService currentRequestExecutorService() {
|
||||||
|
ThreadFactory factory = checkNotNull(ThreadManager.currentRequestThreadFactory(),
|
||||||
|
"ThreadManager.currentRequestThreadFactory()");
|
||||||
|
return MoreExecutors.listeningDecorator(Executors.newCachedThreadPool(factory));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
for (BlobStoreContext context : blobsStoreContexts) {
|
for (View view : views) {
|
||||||
context.close();
|
view.unwrap().close();
|
||||||
}
|
|
||||||
for (ComputeServiceContext context : computeServiceContexts) {
|
|
||||||
context.close();
|
|
||||||
}
|
}
|
||||||
super.contextDestroyed(servletContextEvent);
|
super.contextDestroyed(servletContextEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* 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.samples.googleappengine.domain;
|
||||||
|
|
||||||
|
import static com.google.common.base.Objects.equal;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ResourceResult {
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected String provider;
|
||||||
|
protected String location;
|
||||||
|
protected String type;
|
||||||
|
protected String id;
|
||||||
|
protected String name;
|
||||||
|
|
||||||
|
public Builder provider(String provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder location(String location) {
|
||||||
|
this.location = location;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder type(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder id(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceResult build() {
|
||||||
|
return new ResourceResult(provider, location, type, id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String provider;
|
||||||
|
private final String location;
|
||||||
|
private final String type;
|
||||||
|
private final String id;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
protected ResourceResult(String provider, String location, String type, String id, String name) {
|
||||||
|
this.provider = provider;
|
||||||
|
this.type = type;
|
||||||
|
this.location = location;
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
ResourceResult that = ResourceResult.class.cast(o);
|
||||||
|
return equal(this.provider, that.provider) && equal(this.location, that.location) && equal(this.type, that.type)
|
||||||
|
&& equal(this.id, that.id) && equal(this.name, that.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(provider, location, type, id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper("").add("provider", provider).add("location", location).add("type", type)
|
||||||
|
.add("id", id).add("name", name).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,105 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.samples.googleappengine.domain;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public class StatusResult implements Comparable<StatusResult>, Serializable {
|
|
||||||
/** The serialVersionUID */
|
|
||||||
private static final long serialVersionUID = -3257496189689220018L;
|
|
||||||
private final String service;
|
|
||||||
private final String host;
|
|
||||||
private final String name;
|
|
||||||
private final String status;
|
|
||||||
|
|
||||||
public StatusResult(String service, String host, String name, String status) {
|
|
||||||
this.service = service;
|
|
||||||
this.host = host;
|
|
||||||
this.name = name;
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((host == null) ? 0 : host.hashCode());
|
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
|
||||||
result = prime * result + ((service == null) ? 0 : service.hashCode());
|
|
||||||
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
|
||||||
if (getClass() != obj.getClass())
|
|
||||||
return false;
|
|
||||||
StatusResult other = (StatusResult) obj;
|
|
||||||
if (host == null) {
|
|
||||||
if (other.host != null)
|
|
||||||
return false;
|
|
||||||
} else if (!host.equals(other.host))
|
|
||||||
return false;
|
|
||||||
if (name == null) {
|
|
||||||
if (other.name != null)
|
|
||||||
return false;
|
|
||||||
} else if (!name.equals(other.name))
|
|
||||||
return false;
|
|
||||||
if (service == null) {
|
|
||||||
if (other.service != null)
|
|
||||||
return false;
|
|
||||||
} else if (!service.equals(other.service))
|
|
||||||
return false;
|
|
||||||
if (status == null) {
|
|
||||||
if (other.status != null)
|
|
||||||
return false;
|
|
||||||
} else if (!status.equals(other.status))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(StatusResult o) {
|
|
||||||
return (this == o) ? 0 : getService().compareTo(o.getService());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getService() {
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -18,41 +18,28 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.samples.googleappengine.functions;
|
package org.jclouds.samples.googleappengine.functions;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
|
import org.jclouds.domain.ResourceMetadata;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.samples.googleappengine.domain.StatusResult;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BlobStoreContextToStatusResult implements Function<BlobStoreContext, StatusResult> {
|
public class BlobStoreContextToAsyncResources implements
|
||||||
|
Function<BlobStoreContext, ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> {
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
public StatusResult apply(BlobStoreContext in) {
|
public ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>> apply(BlobStoreContext in) {
|
||||||
String host = URI.create(in.unwrap().getProviderMetadata().getEndpoint()).getHost();
|
logger.info("listing containers on %s: ", in.unwrap().getId());
|
||||||
String status;
|
return in.getAsyncBlobStore().list();
|
||||||
String name = "not found";
|
|
||||||
try {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
|
|
||||||
name = String.format("%d containers", in.getBlobStore().list().size());
|
|
||||||
|
|
||||||
status = ((System.currentTimeMillis() - start) + "ms");
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e, "Error listing context %s", in);
|
|
||||||
status = (e.getMessage());
|
|
||||||
}
|
|
||||||
return new StatusResult(in.unwrap().getId(), host, name, status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* 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.samples.googleappengine.functions;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.domain.ResourceMetadata;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ComputeService doesn't currently have an Async counterpart
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ComputeServiceContextToAsyncResources implements
|
||||||
|
Function<ComputeServiceContext, ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final ListeningExecutorService currentRequestExecutorService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ComputeServiceContextToAsyncResources(ListeningExecutorService currentRequestExecutorService) {
|
||||||
|
this.currentRequestExecutorService = currentRequestExecutorService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>> apply(final ComputeServiceContext in) {
|
||||||
|
return currentRequestExecutorService.submit(new Callable<Iterable<? extends ResourceMetadata<?>>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<? extends ResourceMetadata<?>> call() throws Exception {
|
||||||
|
logger.info("listing nodes on %s: ", in.unwrap().getId());
|
||||||
|
return in.getComputeService().listNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return in.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,14 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.samples.googleappengine.functions;
|
package org.jclouds.samples.googleappengine.functions;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.ResourceMetadata;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.samples.googleappengine.domain.StatusResult;
|
import org.jclouds.samples.googleappengine.domain.ResourceResult;
|
||||||
|
import org.jclouds.samples.googleappengine.domain.ResourceResult.Builder;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
@ -34,25 +34,21 @@ import com.google.common.base.Function;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ComputeServiceContextToStatusResult implements Function<ComputeServiceContext, StatusResult> {
|
public class ResourceMetadataToResourceResult implements Function<ResourceMetadata<?>, ResourceResult> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
public StatusResult apply(ComputeServiceContext in) {
|
public ResourceResult apply(ResourceMetadata<?> in) {
|
||||||
String host = URI.create(in.unwrap().getProviderMetadata().getEndpoint()).getHost();
|
Builder builder = ResourceResult.builder();
|
||||||
String status;
|
Location provider = in.getLocation();
|
||||||
String name = "not found";
|
while (provider.getParent() != null)
|
||||||
try {
|
provider = provider.getParent();
|
||||||
long start = System.currentTimeMillis();
|
builder.provider(provider.getId());
|
||||||
|
builder.location(in.getLocation().getId());
|
||||||
name = String.format("%d nodes", in.getComputeService().listNodes().size());
|
builder.type(in.getType().toString().toLowerCase());
|
||||||
|
builder.id(in.getProviderId());
|
||||||
status = ((System.currentTimeMillis() - start) + "ms");
|
builder.name(in.getName());
|
||||||
} catch (Exception e) {
|
return builder.build();
|
||||||
logger.error(e, "Error listing context %s", in);
|
|
||||||
status = (e.getMessage());
|
|
||||||
}
|
|
||||||
return new StatusResult(in.unwrap().getId(), host, name, status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* 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.samples.googleappengine.functions;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.View;
|
||||||
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.domain.ResourceMetadata;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ViewToAsyncResources implements Function<View, ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>>> {
|
||||||
|
private final BlobStoreContextToAsyncResources blobStoreContextToAsyncResources;
|
||||||
|
private final ComputeServiceContextToAsyncResources computeServiceContextToAsyncResources;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ViewToAsyncResources(BlobStoreContextToAsyncResources blobStoreContextToAsyncResources,
|
||||||
|
ComputeServiceContextToAsyncResources computeServiceContextToAsyncResources) {
|
||||||
|
this.blobStoreContextToAsyncResources = blobStoreContextToAsyncResources;
|
||||||
|
this.computeServiceContextToAsyncResources = computeServiceContextToAsyncResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<? extends Iterable<? extends ResourceMetadata<?>>> apply(View input) {
|
||||||
|
if (input instanceof BlobStoreContext) {
|
||||||
|
return blobStoreContextToAsyncResources.apply(BlobStoreContext.class.cast(input));
|
||||||
|
} else if (input instanceof ComputeServiceContext) {
|
||||||
|
return computeServiceContextToAsyncResources.apply(ComputeServiceContext.class.cast(input));
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException("unknown view type: " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* 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.samples.googleappengine.functions;
|
||||||
|
|
||||||
|
import org.jclouds.View;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
public enum ViewToId implements Function<View, String> {
|
||||||
|
INSTANCE;
|
||||||
|
@Override
|
||||||
|
public String apply(View input) {
|
||||||
|
return input.unwrap().getId();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
<%--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
--%>
|
||||||
|
<%@ page buffer="100kb"%>
|
||||||
|
<%@ taglib uri="http://displaytag.sf.net" prefix="display"%>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>jclouds: multi-cloud library</title>
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
table.staticheader {
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid #CCC;
|
||||||
|
width: 98%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader th {
|
||||||
|
padding: 3px 3px 3px 3px !important;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader td {
|
||||||
|
padding: 3px 3px 3px 3px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader thead tr {
|
||||||
|
position: relative;
|
||||||
|
height: 10px;
|
||||||
|
background-color: #D7E5F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader tbody {
|
||||||
|
height:800px;
|
||||||
|
overflow-x:hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow:scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader tbody tr {
|
||||||
|
height: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader tbody tr.odd {
|
||||||
|
background-color: #eee
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader tbody tr.tableRowEven,tr.even {
|
||||||
|
background-color: #ddd
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader tbody tr td:last-child {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.staticheader tbody td {
|
||||||
|
padding: 2px 4px 2px 4px !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
div.TableContainer {
|
||||||
|
height: 800px;
|
||||||
|
overflow-x:hidden;
|
||||||
|
overflow-y:auto;
|
||||||
|
}
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Resource List</h2>
|
||||||
|
<table width="100%" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="TableContainer">
|
||||||
|
<display:table name="resources" defaultsort="1" cellpadding="5" cellspacing="1" class="staticheader">
|
||||||
|
<display:column property="provider" title="Provider" />
|
||||||
|
<display:column property="location" title="Location" />
|
||||||
|
<display:column property="type" title="Type" />
|
||||||
|
<display:column property="id" title="Id" />
|
||||||
|
<display:column property="name" title="Name" />
|
||||||
|
</display:table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,36 +0,0 @@
|
||||||
<%--
|
|
||||||
|
|
||||||
Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. jclouds licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
--%>
|
|
||||||
<%@ page buffer="20kb"%>
|
|
||||||
<%@ taglib uri="http://displaytag.sf.net" prefix="display"%>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>jclouds: multi-cloud library</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>Status List</h2>
|
|
||||||
<display:table name="status" >
|
|
||||||
<display:column property="service" title="Service" />
|
|
||||||
<display:column property="host" title="Host" />
|
|
||||||
<display:column property="name" title="Item" />
|
|
||||||
<display:column property="status" title="Status" />
|
|
||||||
</display:table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -25,6 +25,6 @@
|
||||||
<body>
|
<body>
|
||||||
<h2>Welcome!</h2>
|
<h2>Welcome!</h2>
|
||||||
Click
|
Click
|
||||||
<a href="/guice/status.check">here</a> to get status of cloud services.
|
<a href="/guice/resources.check">here</a> to list all your cloud resources!
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -18,21 +18,27 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.samples.googleappengine.functest;
|
package org.jclouds.samples.googleappengine.functest;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.util.Maps2;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Parameters;
|
import org.testng.annotations.Parameters;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts up the Google App Engine for Java Development environment and deploys an application which
|
* Starts up the Google App Engine for Java Development environment and deploys an application which
|
||||||
* tests Amazon EC2 and S3.
|
* tests {@link ComputeService} and {@link BlobStore}.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -47,23 +53,37 @@ public class GoogleAppEngineLiveTest {
|
||||||
public void startDevAppServer(final String warfile, final String address, final String port)
|
public void startDevAppServer(final String warfile, final String address, final String port)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
url = new URL(String.format("http://%s:%s", address, port));
|
url = new URL(String.format("http://%s:%s", address, port));
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
String identity = checkNotNull(System.getProperty("test.hpcloud.identity"),
|
props.putAll(stripTestPrefix(selectPropertiesForIdentityAndCredential()));
|
||||||
"test.hpcloud.identity");
|
|
||||||
String credential = checkNotNull(System.getProperty("test.hpcloud.credential"),
|
|
||||||
"test.hpcloud.credential");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Since both objectstorage and compute use the same credentials, we can
|
|
||||||
* take a shortcut and specify both here:
|
|
||||||
*/
|
|
||||||
props.setProperty("jclouds.identity", identity);
|
|
||||||
props.setProperty("jclouds.credential", credential);
|
|
||||||
|
|
||||||
server = new GoogleDevServer();
|
server = new GoogleDevServer();
|
||||||
server.writePropertiesAndStartServer(address, port, warfile, props);
|
server.writePropertiesAndStartServer(address, port, warfile, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, String> stripTestPrefix(Map<String, String> identityCrendential) {
|
||||||
|
return Maps2.transformKeys(identityCrendential, new Function<String, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(String arg0) {
|
||||||
|
return arg0.replace("test.", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
Map<String, String> selectPropertiesForIdentityAndCredential() {
|
||||||
|
return Maps.filterKeys((Map) System.getProperties(), new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return input.matches("^test\\.[a-z0-9-]+\\.(identity|credential)$");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldPass() throws InterruptedException, IOException {
|
public void shouldPass() throws InterruptedException, IOException {
|
||||||
InputStream i = url.openStream();
|
InputStream i = url.openStream();
|
||||||
|
@ -73,15 +93,15 @@ public class GoogleAppEngineLiveTest {
|
||||||
|
|
||||||
@Test(invocationCount = 5, enabled = true)
|
@Test(invocationCount = 5, enabled = true)
|
||||||
public void testGuiceJCloudsSerial() throws InterruptedException, IOException {
|
public void testGuiceJCloudsSerial() throws InterruptedException, IOException {
|
||||||
URL gurl = new URL(url, "/guice/status.check");
|
URL gurl = new URL(url, "/guice/resources.check");
|
||||||
InputStream i = gurl.openStream();
|
InputStream i = gurl.openStream();
|
||||||
String string = Strings2.toStringAndClose(i);
|
String string = Strings2.toStringAndClose(i);
|
||||||
assert string.indexOf("List") >= 0 : string;
|
assert string.indexOf("List") >= 0 : string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(invocationCount = 10, enabled = true, threadPoolSize = 3)
|
@Test(invocationCount = 10, enabled = false, threadPoolSize = 3)
|
||||||
public void testGuiceJCloudsParallel() throws InterruptedException, IOException {
|
public void testGuiceJCloudsParallel() throws InterruptedException, IOException {
|
||||||
URL gurl = new URL(url, "/guice/status.check");
|
URL gurl = new URL(url, "/guice/resources.check");
|
||||||
InputStream i = gurl.openStream();
|
InputStream i = gurl.openStream();
|
||||||
String string = Strings2.toStringAndClose(i);
|
String string = Strings2.toStringAndClose(i);
|
||||||
assert string.indexOf("List") >= 0 : string;
|
assert string.indexOf("List") >= 0 : string;
|
||||||
|
|
Loading…
Reference in New Issue