Issue 89: fixed npe in google appengine live

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2592 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-04 04:25:34 +00:00
parent 69b247cbf4
commit 3087cce540
3 changed files with 148 additions and 150 deletions

View File

@ -13,6 +13,7 @@ import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Singleton;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextBuilder;
@ -37,14 +38,13 @@ import com.google.common.io.Closeables;
* @see SpringServletConfig
*/
@Configuration
@Singleton
public class SpringAppConfig implements ResourceLoaderAware {
/*
* The call to TwitterContextFactory.createContext in initialize()
* must be carried out before the servlet context loads, otherwise the
* GAE will throw an access exception.
* For this reason, this code cannot be in the default servlet context
* loaded by the DispatcherServlet, but is executed in the root application
* context (which is processed by a listener).
* The call to TwitterContextFactory.createContext in initialize() must be carried out before the
* servlet context loads, otherwise the GAE will throw an access exception. For this reason, this
* code cannot be in the default servlet context loaded by the DispatcherServlet, but is executed
* in the root application context (which is processed by a listener).
*/
private final Properties props = new Properties();
@ -53,9 +53,14 @@ public class SpringAppConfig implements ResourceLoaderAware {
TwitterClient twitterClient;
String container;
private boolean initializing;
@SuppressWarnings("unchecked")
@PostConstruct
public void initialize() {
if (initializing)
return;
initializing = true;
// shared across all blobstores and used to retrieve tweets
twitterClient = TwitterContextFactory.createContext(props,
new GaeHttpCommandExecutorServiceModule()).getApi();
@ -63,10 +68,9 @@ public class SpringAppConfig implements ResourceLoaderAware {
// common namespace for storing tweets.
container = checkNotNull(props.getProperty(PROPERTY_TWEETSTORE_CONTAINER),
PROPERTY_TWEETSTORE_CONTAINER);
ImmutableList<String> contextBuilderClassNames = ImmutableList.<String>of(
checkNotNull(props.getProperty(PROPERTY_BLOBSTORE_CONTEXTBUILDERS),
PROPERTY_BLOBSTORE_CONTEXTBUILDERS)
.split(","));
ImmutableList<String> contextBuilderClassNames = ImmutableList.<String> of(checkNotNull(
props.getProperty(PROPERTY_BLOBSTORE_CONTEXTBUILDERS),
PROPERTY_BLOBSTORE_CONTEXTBUILDERS).split(","));
// instantiate and store references to all blobstores by provider name
providerTypeToBlobStoreMap = Maps.newHashMap();
@ -79,9 +83,8 @@ public class SpringAppConfig implements ResourceLoaderAware {
builderClass = (Class<BlobStoreContextBuilder<?, ?>>) Class.forName(className);
name = builderClass.getSimpleName().replaceAll("BlobStoreContextBuilder", "");
constructor = builderClass.getConstructor(Properties.class);
context = constructor.newInstance(props)
.withModules(new GaeHttpCommandExecutorServiceModule())
.buildContext();
context = constructor.newInstance(props).withModules(
new GaeHttpCommandExecutorServiceModule()).buildContext();
} catch (Exception e) {
throw new RuntimeException("error instantiating " + className, e);
}
@ -106,8 +109,7 @@ public class SpringAppConfig implements ResourceLoaderAware {
/*
* (non-Javadoc)
*
* @see
* org.springframework.context.ResourceLoaderAware#setResourceLoader(org
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org
* .springframework.core.io.ResourceLoader)
*/
@Override
@ -116,6 +118,8 @@ public class SpringAppConfig implements ResourceLoaderAware {
try {
input = resourceLoader.getResource("/WEB-INF/jclouds.properties").getInputStream();
props.load(input);
if (!initializing)
initialize();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {

View File

@ -1,21 +1,33 @@
/**
*
* 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.demo.tweetstore.config;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import javax.inject.Inject;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import org.jclouds.demo.tweetstore.controller.AddTweetsController;
import org.jclouds.demo.tweetstore.controller.StoreTweetsController;
import org.jclouds.demo.tweetstore.functions.ServiceToStoredTweetStatuses;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ServletConfigAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
@ -24,59 +36,46 @@ import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import com.google.common.collect.Maps;
/**
* Creates servlets (using resources from the {@link SpringAppConfig}) and mappings.
* Creates servlets,(using resources from the {@link SpringAppConfig}) and mappings.
*
* @author Andrew Phillips
* @see SpringAppConfig
*/
@Configuration
public class SpringServletConfig implements ServletConfigAware {
private ServletConfig servletConfig;
@Inject
private SpringAppConfig appConfig;
public class SpringServletConfig {
@Bean
public StoreTweetsController storeTweetsController() {
StoreTweetsController controller = new StoreTweetsController(appConfig.providerTypeToBlobStoreMap,
appConfig.container, appConfig.twitterClient);
injectServletConfig(controller);
return controller;
public StoreTweetsController storeTweetsController(SpringAppConfig appConfig) {
return new StoreTweetsController(checkNotNull(appConfig.providerTypeToBlobStoreMap,
"contexts"), checkNotNull(appConfig.container, "container"), checkNotNull(
appConfig.twitterClient, "twitterClient"));
}
@Bean
public AddTweetsController addTweetsController() {
AddTweetsController controller = new AddTweetsController(appConfig.providerTypeToBlobStoreMap,
serviceToStoredTweetStatuses());
injectServletConfig(controller);
return controller;
}
private void injectServletConfig(Servlet servlet) {
checkNotNull(servletConfig);
try {
servlet.init(servletConfig);
} catch (ServletException exception) {
throw new BeanCreationException("Unable to instantiate " + servlet, exception);
}
public AddTweetsController addTweetsController(SpringAppConfig appConfig) {
return new AddTweetsController(
checkNotNull(appConfig.providerTypeToBlobStoreMap, "contexts"),
serviceToStoredTweetStatuses(appConfig));
}
@Bean
ServiceToStoredTweetStatuses serviceToStoredTweetStatuses() {
return new ServiceToStoredTweetStatuses(appConfig.providerTypeToBlobStoreMap,
appConfig.container);
ServiceToStoredTweetStatuses serviceToStoredTweetStatuses(SpringAppConfig appConfig) {
return new ServiceToStoredTweetStatuses(checkNotNull(appConfig.providerTypeToBlobStoreMap,
"contexts"), checkNotNull(appConfig.container, "container"));
}
@Bean
public HandlerMapping handlerMapping() {
public HandlerMapping handlerMapping(AddTweetsController add, StoreTweetsController store,
WebApplicationContext context) {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setServletContext(context.getServletContext());
Map<String, Object> urlMap = Maps.newHashMapWithExpectedSize(2);
urlMap.put("/store/*", storeTweetsController());
urlMap.put("/tweets/*", addTweetsController());
urlMap.put("/store/*", checkNotNull(store, "store"));
add.setServletContext(checkNotNull(context.getServletContext(), "servletContext"));
urlMap.put("/tweets/*", checkNotNull(add, "add"));
mapping.setUrlMap(urlMap);
/*
* "/store" and "/tweets" are part of the servlet mapping and thus stripped
* by the mapping if using default settings.
* "/store" and "/tweets" are part of the servlet mapping and thus stripped by the mapping if
* using default settings.
*/
mapping.setAlwaysUseFullPath(true);
return mapping;
@ -86,12 +85,5 @@ public class SpringServletConfig implements ServletConfigAware {
public HandlerAdapter servletHandlerAdapter() {
return new SimpleServletHandlerAdapter();
}
/* (non-Javadoc)
* @see org.springframework.web.context.ServletConfigAware#setServletConfig(javax.servlet.ServletConfig)
*/
@Override
public void setServletConfig(ServletConfig servletConfig) {
this.servletConfig = servletConfig;
}
}

View File

@ -69,8 +69,9 @@ public class AddTweetsController extends HttpServlet implements
@Inject
public AddTweetsController(Map<String, BlobStoreContext<?, ?>> contexts,
ServiceToStoredTweetStatuses blobStoreContextToContainerResult) {
this.contexts = contexts;
this.blobStoreContextToContainerResult = blobStoreContextToContainerResult;
this.contexts = checkNotNull(contexts, "contexts");
this.blobStoreContextToContainerResult = checkNotNull(blobStoreContextToContainerResult,
"blobStoreContextToContainerResult");
}
@Override
@ -100,6 +101,7 @@ public class AddTweetsController extends HttpServlet implements
return statuses;
}
@Inject
@Override
public void setServletContext(ServletContext context) {
this.servletContext = context;
@ -107,6 +109,6 @@ public class AddTweetsController extends HttpServlet implements
@Override
public ServletContext getServletContext() {
return checkNotNull(servletContext, "servletContext");
return (servletContext != null) ? servletContext : super.getServletContext();
}
}