Using the new context view (see http://code.google.com/p/jclouds/issues/detail?id=904) in cf-tweetstore-spring

This commit is contained in:
Andrew Phillips 2012-04-26 01:45:31 -04:00
parent 8be906301e
commit 13abe19cb2
13 changed files with 127 additions and 82 deletions

View File

@ -0,0 +1,65 @@
/**
* 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.demo.paas.config;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.inject.name.Names.bindProperties;
import static org.jclouds.Constants.*;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.demo.tweetstore.config.util.PropertiesLoader;
import com.google.inject.AbstractModule;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* @author Andrew Phillips
*/
public class HttpClientModule extends AbstractModule {
private final ServletContext context;
HttpClientModule(ServletContext context) {
this.context = context;
}
@Override
protected void configure() {
// URL connection defaults
Properties toBind = defaultProperties();
toBind.putAll(checkNotNull(new PropertiesLoader(context).get(), "properties"));
toBind.putAll(System.getProperties());
bindProperties(binder(), toBind);
bind(UriBuilder.class).to(UriBuilderImpl.class);
}
private static Properties defaultProperties() {
Properties props = new Properties();
props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, 20 + "");
props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_HOST, 0 + "");
props.setProperty(PROPERTY_SO_TIMEOUT, 60000 + "");
props.setProperty(PROPERTY_CONNECTION_TIMEOUT, 60000 + "");
props.setProperty(PROPERTY_USER_THREADS, 0 + "");
props.setProperty(PROPERTY_IO_WORKER_THREADS, 20 + "");
return props;
}
}

View File

@ -18,34 +18,24 @@
*/
package org.jclouds.demo.paas.config;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.inject.name.Names.bindProperties;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.ws.rs.core.UriBuilder;
import org.cloudfoundry.runtime.env.ApplicationInstanceInfo;
import org.cloudfoundry.runtime.env.CloudEnvironment;
import org.jclouds.PropertiesBuilder;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.demo.paas.PlatformServices;
import org.jclouds.demo.paas.service.scheduler.Scheduler;
import org.jclouds.demo.paas.service.taskqueue.TaskQueue;
import org.jclouds.demo.tweetstore.config.util.PropertiesLoader;
import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.sun.jersey.api.uri.UriBuilderImpl;
/**
* @author Andrew Phillips
@ -69,27 +59,14 @@ public class PlatformServicesInitializer implements ServletContextListener {
final ServletContext context) {
return Guice.createInjector(new ExecutorServiceModule(),
new JavaUrlHttpCommandExecutorServiceModule(),
new AbstractModule() {
@Override
protected void configure() {
// URL connection defaults
Properties toBind = new PropertiesBuilder().build();
toBind.putAll(checkNotNull(new PropertiesLoader(context).get(), "properties"));
toBind.putAll(System.getProperties());
bindProperties(binder(), toBind);
bind(UriBuilder.class).to(UriBuilderImpl.class);
}
}).getInstance(HttpCommandExecutorService.class);
new HttpClientModule(context))
.getInstance(HttpCommandExecutorService.class);
}
protected static String getBaseUrl(ServletContext context) {
ApplicationInstanceInfo instanceInfo = new CloudEnvironment().getInstanceInfo();
// TODO: use internal address if possible. See http://support.cloudfoundry.com/requests/102117
// return "http://" + checkNotNull(instanceInfo.getHost(), "instanceInfo.getHost()")
// + ":" + instanceInfo.getPort() + context.getContextPath();
checkState(!instanceInfo.getUris().isEmpty(), "instanceInfo.getUris() is empty");
return "http://" + checkNotNull(instanceInfo.getUris().get(0), "instanceInfo.getUris().get(0)")
+ context.getContextPath();
// using localhost instead of instanceInfo.getHost(). See http://support.cloudfoundry.com/requests/102117
return "http://127.0.0.1:" + instanceInfo.getPort() + context.getContextPath();
}
// TODO: make the number and names of queues configurable

View File

@ -42,8 +42,8 @@ import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.demo.paas.PlatformServices;
import org.jclouds.demo.paas.service.taskqueue.TaskQueue;
import org.jclouds.demo.tweetstore.config.util.CredentialsCollector;
@ -85,7 +85,7 @@ public class SpringServletConfig extends LoggingConfig implements ServletConfigA
private ServletConfig servletConfig;
private Map<String, BlobStoreContext<?, ?>> providerTypeToBlobStoreMap;
private Map<String, BlobStoreContext> providerTypeToBlobStoreMap;
private Twitter twitterClient;
private String container;
private TaskQueue queue;
@ -115,8 +115,8 @@ public class SpringServletConfig extends LoggingConfig implements ServletConfigA
// instantiate and store references to all blobstores by provider name
providerTypeToBlobStoreMap = Maps.newHashMap();
for (String hint : getBlobstoreContexts(props)) {
providerTypeToBlobStoreMap.put(hint, BlobStoreContextBuilder
.newBuilder(hint).modules(modules).overrides(props).build());
providerTypeToBlobStoreMap.put(hint, ContextBuilder.newBuilder(hint)
.modules(modules).overrides(props).build(BlobStoreContext.class));
}
// get a queue for submitting store tweet requests and the application's base URL
@ -212,7 +212,7 @@ public class SpringServletConfig extends LoggingConfig implements ServletConfigA
@PreDestroy
public void destroy() throws Exception {
LOGGER.trace("About to close contexts.");
for (BlobStoreContext<?, ?> context : providerTypeToBlobStoreMap.values()) {
for (BlobStoreContext context : providerTypeToBlobStoreMap.values()) {
context.close();
}
LOGGER.trace("Contexts closed.");

View File

@ -54,14 +54,14 @@ public class AddTweetsController extends HttpServlet implements
/** The serialVersionUID */
private static final long serialVersionUID = 3888348023150822683L;
private final Map<String, BlobStoreContext<?, ?>> contexts;
private final Map<String, BlobStoreContext> contexts;
private final ServiceToStoredTweetStatuses blobStoreContextToContainerResult;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public AddTweetsController(Map<String, BlobStoreContext<?, ?>> contexts,
public AddTweetsController(Map<String, BlobStoreContext> contexts,
ServiceToStoredTweetStatuses blobStoreContextToContainerResult) {
this.contexts = contexts;
this.blobStoreContextToContainerResult = blobStoreContextToContainerResult;

View File

@ -65,7 +65,7 @@ public class EnqueueStoresController extends HttpServlet {
protected Logger logger = Logger.NULL;
@Inject
public EnqueueStoresController(Map<String, BlobStoreContext<?, ?>> contexts, TaskQueue taskQueue,
public EnqueueStoresController(Map<String, BlobStoreContext> contexts, TaskQueue taskQueue,
@Named(PaasConstants.PROPERTY_PLATFORM_BASE_URL) String baseUrl) {
contextNames = contexts.keySet();
this.taskQueue = taskQueue;

View File

@ -75,7 +75,7 @@ public class StoreTweetsController extends HttpServlet {
/** The serialVersionUID */
private static final long serialVersionUID = 7215420527854203714L;
private final Map<String, BlobStoreContext<?, ?>> contexts;
private final Map<String, BlobStoreContext> contexts;
private final Twitter client;
private final String container;
@ -84,7 +84,7 @@ public class StoreTweetsController extends HttpServlet {
@Inject
@VisibleForTesting
public StoreTweetsController(Map<String, BlobStoreContext<?, ?>> contexts,
public StoreTweetsController(Map<String, BlobStoreContext> contexts,
@Named(TweetStoreConstants.PROPERTY_TWEETSTORE_CONTAINER) String container, Twitter client) {
this.container = container;
this.contexts = contexts;
@ -93,7 +93,7 @@ public class StoreTweetsController extends HttpServlet {
@VisibleForTesting
public void addMyTweets(String contextName, Iterable<Status> responseList) {
BlobStoreContext<?, ?> context = checkNotNull(contexts.get(contextName), "no context for " + contextName + " in "
BlobStoreContext context = checkNotNull(contexts.get(contextName), "no context for " + contextName + " in "
+ contexts.keySet());
BlobMap map = context.createBlobMap(container);
for (Status status : responseList) {

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.demo.tweetstore.functions;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@ -27,6 +28,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Context;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.demo.tweetstore.domain.StoredTweetStatus;
@ -39,11 +41,11 @@ import com.google.common.collect.Iterables;
@Singleton
public class ServiceToStoredTweetStatuses implements Function<String, Iterable<StoredTweetStatus>> {
private final Map<String, BlobStoreContext<?, ?>> contexts;
private final Map<String, BlobStoreContext> contexts;
private final String container;
@Inject
public ServiceToStoredTweetStatuses(Map<String, BlobStoreContext<?, ?>> contexts,
public ServiceToStoredTweetStatuses(Map<String, BlobStoreContext> contexts,
@Named(TweetStoreConstants.PROPERTY_TWEETSTORE_CONTAINER) String container) {
this.contexts = contexts;
this.container = container;
@ -53,8 +55,8 @@ public class ServiceToStoredTweetStatuses implements Function<String, Iterable<S
protected Logger logger = Logger.NULL;
public Iterable<StoredTweetStatus> apply(String service) {
BlobStoreContext<?, ?> context = contexts.get(service);
String host = context.getProviderSpecificContext().getEndpoint().getHost();
BlobStoreContext context = contexts.get(service);
String host = URI.create(context.unwrap(Context.class).getProviderMetadata().getEndpoint()).getHost();
try {
BlobMap blobMap = context.createBlobMap(container);
Set<String> blobs = blobMap.keySet();

View File

@ -25,8 +25,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.blobstore.TransientApiMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.demo.tweetstore.domain.StoredTweetStatus;
@ -46,12 +46,12 @@ import com.google.common.collect.ImmutableSet;
@Test(groups = "unit")
public class AddTweetsControllerTest {
Map<String, BlobStoreContext<?, ?>> createServices(String container) throws InterruptedException,
Map<String, BlobStoreContext> createServices(String container) throws InterruptedException,
ExecutionException {
Map<String, BlobStoreContext<?, ?>> services = Maps.newHashMap();
Map<String, BlobStoreContext> services = Maps.newHashMap();
TransientApiMetadata transientApiMetadata = TransientApiMetadata.builder().build();
for (String name : new String[] { "1", "2" }) {
BlobStoreContext<?, ?> context = BlobStoreContextBuilder.newBuilder(transientApiMetadata).build();
BlobStoreContext context = ContextBuilder.newBuilder(transientApiMetadata).build(BlobStoreContext.class);
context.getAsyncBlobStore().createContainerInLocation(null, container).get();
Blob blob = context.getAsyncBlobStore().blobBuilder("1").build();
blob.getMetadata().getUserMetadata().put(TweetStoreConstants.SENDER_NAME, "frank");
@ -64,7 +64,7 @@ public class AddTweetsControllerTest {
public void testStoreTweets() throws IOException, InterruptedException, ExecutionException {
String container = "container";
Map<String, BlobStoreContext<?, ?>> contexts = createServices(container);
Map<String, BlobStoreContext> contexts = createServices(container);
ServiceToStoredTweetStatuses function = new ServiceToStoredTweetStatuses(contexts, container);
AddTweetsController controller = new AddTweetsController(contexts, function);

View File

@ -23,8 +23,8 @@ import static org.easymock.EasyMock.*;
import java.net.URI;
import java.util.Map;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.blobstore.TransientApiMetadata;
import org.jclouds.demo.paas.RunnableHttpRequest;
import org.jclouds.demo.paas.RunnableHttpRequest.Factory;
@ -43,16 +43,16 @@ import com.google.common.collect.ImmutableMultimap;
@Test(groups = "unit")
public class EnqueueStoresControllerTest {
Map<String, BlobStoreContext<?, ?>> createBlobStores() {
Map<String, BlobStoreContext> createBlobStores() {
TransientApiMetadata transientApiMetadata = TransientApiMetadata.builder().build();
Map<String, BlobStoreContext<?, ?>> contexts = ImmutableMap.<String, BlobStoreContext<?, ?>>of(
"test1", BlobStoreContextBuilder.newBuilder(transientApiMetadata).build(),
"test2", BlobStoreContextBuilder.newBuilder(transientApiMetadata).build());
Map<String, BlobStoreContext> contexts = ImmutableMap.<String, BlobStoreContext>of(
"test1", ContextBuilder.newBuilder(transientApiMetadata).build(BlobStoreContext.class),
"test2", ContextBuilder.newBuilder(transientApiMetadata).build(BlobStoreContext.class));
return contexts;
}
public void testEnqueueStores() {
Map<String, BlobStoreContext<?, ?>> stores = createBlobStores();
Map<String, BlobStoreContext> stores = createBlobStores();
TaskQueue taskQueue = createMock(TaskQueue.class);
Factory httpRequestFactory = createMock(Factory.class);
EnqueueStoresController function = new EnqueueStoresController(stores,

View File

@ -30,9 +30,9 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.blobstore.TransientApiMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.demo.tweetstore.reference.TweetStoreConstants;
@ -57,19 +57,19 @@ public class StoreTweetsControllerTest {
return createMock(Twitter.class);
}
Map<String, BlobStoreContext<?, ?>> createBlobStores() throws InterruptedException, ExecutionException {
Map<String, BlobStoreContext> createBlobStores() throws InterruptedException, ExecutionException {
TransientApiMetadata transientApiMetadata = TransientApiMetadata.builder().build();
Map<String, BlobStoreContext<?, ?>> contexts = ImmutableMap.<String, BlobStoreContext<?, ?>>of(
"test1", BlobStoreContextBuilder.newBuilder(transientApiMetadata).build(),
"test2", BlobStoreContextBuilder.newBuilder(transientApiMetadata).build());
for (BlobStoreContext<?, ?> blobstore : contexts.values()) {
Map<String, BlobStoreContext> contexts = ImmutableMap.<String, BlobStoreContext>of(
"test1", ContextBuilder.newBuilder(transientApiMetadata).build(BlobStoreContext.class),
"test2", ContextBuilder.newBuilder(transientApiMetadata).build(BlobStoreContext.class));
for (BlobStoreContext blobstore : contexts.values()) {
blobstore.getAsyncBlobStore().createContainerInLocation(null, "favo").get();
}
return contexts;
}
public void testStoreTweets() throws IOException, InterruptedException, ExecutionException {
Map<String, BlobStoreContext<?, ?>> stores = createBlobStores();
Map<String, BlobStoreContext> stores = createBlobStores();
StoreTweetsController function = new StoreTweetsController(stores, "favo", createTwitter());
User frank = createMock(User.class);
@ -101,7 +101,7 @@ public class StoreTweetsControllerTest {
verify(jimmy);
verify(jimmyStatus);
for (Entry<String, BlobStoreContext<?, ?>> entry : stores.entrySet()) {
for (Entry<String, BlobStoreContext> entry : stores.entrySet()) {
BlobMap map = entry.getValue().createBlobMap("favo");
Blob frankBlob = map.get("1");
assertEquals(frankBlob.getMetadata().getName(), "1");

View File

@ -23,9 +23,9 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.blobstore.TransientApiMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.demo.tweetstore.domain.StoredTweetStatus;
@ -41,8 +41,8 @@ import org.testng.annotations.Test;
public class KeyToStoredTweetStatusTest {
BlobMap createMap() throws InterruptedException, ExecutionException {
BlobStoreContext<?, ?> context =
BlobStoreContextBuilder.newBuilder(TransientApiMetadata.builder().build()).build();
BlobStoreContext context =
ContextBuilder.newBuilder(TransientApiMetadata.builder().build()).build(BlobStoreContext.class);
context.getBlobStore().createContainerInLocation(null, "test1");
return context.createBlobMap("test1");
}

View File

@ -24,8 +24,8 @@ import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.blobstore.TransientApiMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.demo.tweetstore.domain.StoredTweetStatus;
@ -43,12 +43,12 @@ import com.google.common.collect.Iterables;
@Test(groups = "unit")
public class ServiceToStoredTweetStatusesTest {
Map<String, BlobStoreContext<?, ?>> createServices(String container) throws InterruptedException,
Map<String, BlobStoreContext> createServices(String container) throws InterruptedException,
ExecutionException {
Map<String, BlobStoreContext<?, ?>> services = Maps.newHashMap();
Map<String, BlobStoreContext> services = Maps.newHashMap();
TransientApiMetadata transientApiMetadata = TransientApiMetadata.builder().build();
for (String name : new String[] { "1", "2" }) {
BlobStoreContext<?, ?> context = BlobStoreContextBuilder.newBuilder(transientApiMetadata).build();
BlobStoreContext context = ContextBuilder.newBuilder(transientApiMetadata).build(BlobStoreContext.class);
context.getAsyncBlobStore().createContainerInLocation(null, container).get();
Blob blob = context.getAsyncBlobStore().blobBuilder("1").build();
blob.getMetadata().getUserMetadata().put(TweetStoreConstants.SENDER_NAME, "frank");
@ -61,7 +61,7 @@ public class ServiceToStoredTweetStatusesTest {
public void testStoreTweets() throws IOException, InterruptedException, ExecutionException {
String container = "container";
Map<String, BlobStoreContext<?, ?>> contexts = createServices(container);
Map<String, BlobStoreContext> contexts = createServices(container);
ServiceToStoredTweetStatuses function = new ServiceToStoredTweetStatuses(contexts, container);

View File

@ -37,8 +37,9 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.Context;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.demo.tweetstore.config.SpringServletConfig;
import org.jclouds.demo.tweetstore.controller.StoreTweetsController;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -73,7 +74,7 @@ public class TweetStoreLiveTest {
CloudFoundryServer server;
private URL url;
private Map<String, BlobStoreContext<?, ?>> contexts;
private Map<String, BlobStoreContext> contexts;
private String container;
private static final Iterable<String> blobstores =
@ -100,8 +101,8 @@ public class TweetStoreLiveTest {
this.contexts = Maps.newConcurrentMap();
for (String provider : blobstores) {
contexts.put(provider, BlobStoreContextBuilder.newBuilder(provider)
.modules(wiring).overrides(props).build());
contexts.put(provider, ContextBuilder.newBuilder(provider).modules(wiring)
.overrides(props).build(BlobStoreContext.class));
}
Configuration conf = new ConfigurationBuilder()
@ -116,10 +117,10 @@ public class TweetStoreLiveTest {
ResponseList<Status> statuses = client.getMentions();
boolean deleted = false;
for (BlobStoreContext<?, ?> context : contexts.values()) {
for (BlobStoreContext context : contexts.values()) {
if (context.getBlobStore().containerExists(container)) {
System.err.printf("deleting container %s at %s%n", container, context.getProviderSpecificContext()
.getEndpoint());
System.err.printf("deleting container %s at %s%n", container,
context.unwrap(Context.class).getProviderMetadata().getEndpoint());
context.getBlobStore().deleteContainer(container);
deleted = true;
}
@ -128,9 +129,9 @@ public class TweetStoreLiveTest {
System.err.println("sleeping 60 seconds to allow containers to clear");
Thread.sleep(60000);
}
for (BlobStoreContext<?, ?> context : contexts.values()) {
System.err.printf("creating container %s at %s%n", container, context.getProviderSpecificContext()
.getEndpoint());
for (BlobStoreContext context : contexts.values()) {
System.err.printf("creating container %s at %s%n", container,
context.unwrap(Context.class).getProviderMetadata().getEndpoint());
context.getBlobStore().createContainerInLocation(null, container);
}
if (deleted) {
@ -138,7 +139,7 @@ public class TweetStoreLiveTest {
Thread.sleep(5000);
}
for (Entry<String, BlobStoreContext<?, ?>> entry : contexts.entrySet()) {
for (Entry<String, BlobStoreContext> entry : contexts.entrySet()) {
System.err.printf("filling container %s at %s%n", container, entry.getKey());
controller.addMyTweets(entry.getKey(), statuses);
}
@ -205,8 +206,8 @@ public class TweetStoreLiveTest {
System.err.println("sleeping 20 seconds to allow for eventual consistency delay");
Thread.sleep(20000);
for (BlobStoreContext<?, ?> context : contexts.values()) {
assert context.createInputStreamMap(container).size() > 0 : context.getProviderSpecificContext().getEndpoint();
for (BlobStoreContext context : contexts.values()) {
assert context.createInputStreamMap(container).size() > 0 : context.unwrap(Context.class).getProviderMetadata().getEndpoint();
}
}