Replaced @PostConstruct and @PreDestroy with Initializing- and DisposableBean, resp., since the bean post processor responsible for supporting the annotations doesn't register on GAE.

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2596 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
sharedocs1@gmail.com 2010-01-04 21:04:56 +00:00
parent dea9a75c66
commit 6dc3735bb0
1 changed files with 122 additions and 87 deletions

View File

@ -1,3 +1,21 @@
/**
*
* 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.appengine.api.labs.taskqueue.TaskOptions.Builder.url;
@ -11,15 +29,13 @@ import java.lang.reflect.Constructor;
import java.util.Map;
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;
import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule;
import org.jclouds.twitter.TwitterClient;
import org.jclouds.twitter.TwitterContextFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
@ -38,92 +54,111 @@ 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).
*/
public class SpringAppConfig extends LoggingConfig implements InitializingBean, DisposableBean, 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).
*
* Note that none of the common annotations (such as @PostConstruct)
* will work here because Spring does not detect JSR-250 support (since it
* cannot load javax.annotation.Resource).
*/
Map<String, BlobStoreContext<?, ?>> providerTypeToBlobStoreMap;
TwitterClient twitterClient;
String container;
private final Properties props = new Properties();
private final Properties props = new Properties();
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@SuppressWarnings("unchecked")
@Override
public void afterPropertiesSet() throws Exception {
logger.trace("About to initialize properties.");
// shared across all blobstores and used to retrieve tweets
twitterClient = TwitterContextFactory.createContext(props,
new GaeHttpCommandExecutorServiceModule()).getApi();
Map<String, BlobStoreContext<?, ?>> providerTypeToBlobStoreMap;
TwitterClient twitterClient;
String container;
// 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(","));
private boolean initializing;
// instantiate and store references to all blobstores by provider name
providerTypeToBlobStoreMap = Maps.newHashMap();
for (String className : contextBuilderClassNames) {
Class<BlobStoreContextBuilder<?, ?>> builderClass;
Constructor<BlobStoreContextBuilder<?, ?>> constructor;
String name;
BlobStoreContext<?, ?> context;
try {
builderClass = (Class<BlobStoreContextBuilder<?, ?>>) Class.forName(className);
name = builderClass.getSimpleName().replaceAll("BlobStoreContextBuilder", "");
constructor = builderClass.getConstructor(Properties.class);
context = constructor.newInstance(props)
.withModules(new GaeHttpCommandExecutorServiceModule())
.buildContext();
} catch (Exception e) {
throw new RuntimeException("error instantiating " + className, e);
}
providerTypeToBlobStoreMap.put(name, context);
}
@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();
// get a queue for submitting store tweet requests
Queue queue = QueueFactory.getQueue("twitter");
// submit a job to store tweets for each configured blobstore
for (String name : providerTypeToBlobStoreMap.keySet()) {
queue.add(url("/store/do").header("context", name).method(Method.GET));
}
logger.trace("Properties initialized. TwitterClient: '%s', container: '%s', provider types: '%s'",
twitterClient, container, providerTypeToBlobStoreMap.keySet());
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
public void destroy() throws Exception {
logger.trace("About to close contexts.");
for (BlobStoreContext<?, ?> context : providerTypeToBlobStoreMap.values()) {
context.close();
}
logger.trace("Contexts closed.");
}
// 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(","));
// instantiate and store references to all blobstores by provider name
providerTypeToBlobStoreMap = Maps.newHashMap();
for (String className : contextBuilderClassNames) {
Class<BlobStoreContextBuilder<?, ?>> builderClass;
Constructor<BlobStoreContextBuilder<?, ?>> constructor;
String name;
BlobStoreContext<?, ?> context;
try {
builderClass = (Class<BlobStoreContextBuilder<?, ?>>) Class.forName(className);
name = builderClass.getSimpleName().replaceAll("BlobStoreContextBuilder", "");
constructor = builderClass.getConstructor(Properties.class);
context = constructor.newInstance(props).withModules(
new GaeHttpCommandExecutorServiceModule()).buildContext();
} catch (Exception e) {
throw new RuntimeException("error instantiating " + className, e);
}
providerTypeToBlobStoreMap.put(name, context);
}
// get a queue for submitting store tweet requests
Queue queue = QueueFactory.getQueue("twitter");
// submit a job to store tweets for each configured blobstore
for (String name : providerTypeToBlobStoreMap.keySet()) {
queue.add(url("/store/do").header("context", name).method(Method.GET));
}
}
@PreDestroy
public void destroy() {
for (BlobStoreContext<?, ?> context : providerTypeToBlobStoreMap.values()) {
context.close();
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org
* .springframework.core.io.ResourceLoader)
*/
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
InputStream input = null;
try {
input = resourceLoader.getResource("/WEB-INF/jclouds.properties").getInputStream();
props.load(input);
if (!initializing)
initialize();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
Closeables.closeQuietly(input);
}
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.context.ResourceLoaderAware#setResourceLoader(org
* .springframework.core.io.ResourceLoader)
*/
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
logger.trace("About to read properties from '%s'", "/WEB-INF/jclouds.properties");
InputStream input = null;
try {
input = resourceLoader.getResource("/WEB-INF/jclouds.properties").getInputStream();
props.load(input);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
Closeables.closeQuietly(input);
}
logger.trace("Properties successfully read.");
}
}