diff --git a/aws/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java b/aws/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java index 157fa98501..a4402e55e1 100755 --- a/aws/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java +++ b/aws/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java @@ -31,7 +31,7 @@ import javax.servlet.ServletContextEvent; import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContextBuilder; import org.jclouds.blobstore.reference.BlobStoreConstants; -import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule; +import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; import org.jclouds.samples.googleappengine.GetAllContainersController; import com.google.appengine.repackaged.com.google.common.collect.ImmutableList; @@ -68,7 +68,7 @@ public class GuiceServletConfig extends GuiceServletContextListener { Constructor> constructor = builderClass .getConstructor(Properties.class); contexts.put(name, constructor.newInstance(props).withModules( - new GaeHttpCommandExecutorServiceModule()).buildContext()); + new GoogleAppEngineConfigurationModule()).buildContext()); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/aws/perftest/src/test/java/org/jclouds/aws/s3/JCloudsGaePerformanceLiveTest.java b/aws/perftest/src/test/java/org/jclouds/aws/s3/JCloudsGaePerformanceLiveTest.java index f11500c0a6..eeb17f7dc9 100755 --- a/aws/perftest/src/test/java/org/jclouds/aws/s3/JCloudsGaePerformanceLiveTest.java +++ b/aws/perftest/src/test/java/org/jclouds/aws/s3/JCloudsGaePerformanceLiveTest.java @@ -24,16 +24,14 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.jclouds.date.joda.config.JodaDateServiceModule; -import org.jclouds.encryption.bouncycastle.config.BouncyCastleEncryptionServiceModule; -import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule; -import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; +import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.testng.v6.Maps; import com.google.appengine.tools.development.ApiProxyLocalImpl; import com.google.apphosting.api.ApiProxy; +import com.google.inject.Module; /** * @@ -152,16 +150,6 @@ public class JCloudsGaePerformanceLiveTest extends BaseJCloudsPerformanceLiveTes }); } - @ConfiguresHttpCommandExecutorService - private static final class Module extends GaeHttpCommandExecutorServiceModule { - @Override - protected void configure() { - super.configure(); - install(new JodaDateServiceModule()); - install(new BouncyCastleEncryptionServiceModule()); - } - } - class TestEnvironment implements ApiProxy.Environment { public String getAppId() { return "Unit Tests"; @@ -205,6 +193,6 @@ public class JCloudsGaePerformanceLiveTest extends BaseJCloudsPerformanceLiveTes @Override protected Module createHttpModule() { - return new Module(); + return new GoogleAppEngineConfigurationModule(); } } \ No newline at end of file diff --git a/demos/gae-tweetstore-spring/src/main/java/org/jclouds/demo/tweetstore/config/SpringServletConfig.java b/demos/gae-tweetstore-spring/src/main/java/org/jclouds/demo/tweetstore/config/SpringServletConfig.java index 6b0aceb9b9..bcf747c6da 100644 --- a/demos/gae-tweetstore-spring/src/main/java/org/jclouds/demo/tweetstore/config/SpringServletConfig.java +++ b/demos/gae-tweetstore-spring/src/main/java/org/jclouds/demo/tweetstore/config/SpringServletConfig.java @@ -40,7 +40,7 @@ import org.jclouds.blobstore.BlobStoreContextBuilder; import org.jclouds.demo.tweetstore.controller.AddTweetsController; import org.jclouds.demo.tweetstore.controller.StoreTweetsController; import org.jclouds.demo.tweetstore.functions.ServiceToStoredTweetStatuses; -import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule; +import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; import org.jclouds.twitter.TwitterClient; import org.jclouds.twitter.TwitterContextFactory; import org.springframework.beans.factory.BeanCreationException; @@ -81,7 +81,7 @@ public class SpringServletConfig extends LoggingConfig implements ServletConfigA // shared across all blobstores and used to retrieve tweets twitterClient = TwitterContextFactory.createContext(props, - new GaeHttpCommandExecutorServiceModule()).getApi(); + new GoogleAppEngineConfigurationModule()).getApi(); // common namespace for storing tweets container = checkNotNull(props.getProperty(PROPERTY_TWEETSTORE_CONTAINER), @@ -103,7 +103,7 @@ public class SpringServletConfig extends LoggingConfig implements ServletConfigA name = builderClass.getSimpleName().replaceAll("BlobStoreContextBuilder", ""); constructor = builderClass.getConstructor(Properties.class); context = constructor.newInstance(props) - .withModules(new GaeHttpCommandExecutorServiceModule()) + .withModules(new GoogleAppEngineConfigurationModule()) .buildContext(); } catch (Exception e) { throw new RuntimeException("error instantiating " + className, e); diff --git a/demos/gae-tweetstore/src/main/java/org/jclouds/demo/tweetstore/config/GuiceServletConfig.java b/demos/gae-tweetstore/src/main/java/org/jclouds/demo/tweetstore/config/GuiceServletConfig.java index 5abeb35752..b1f17f5e55 100755 --- a/demos/gae-tweetstore/src/main/java/org/jclouds/demo/tweetstore/config/GuiceServletConfig.java +++ b/demos/gae-tweetstore/src/main/java/org/jclouds/demo/tweetstore/config/GuiceServletConfig.java @@ -35,7 +35,7 @@ import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContextBuilder; import org.jclouds.demo.tweetstore.controller.AddTweetsController; import org.jclouds.demo.tweetstore.controller.StoreTweetsController; -import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule; +import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; import org.jclouds.twitter.TwitterClient; import org.jclouds.twitter.TwitterContextFactory; @@ -71,7 +71,7 @@ public class GuiceServletConfig extends GuiceServletContextListener { // shared across all blobstores and used to retrieve tweets twitterClient = TwitterContextFactory.createContext(props, - new GaeHttpCommandExecutorServiceModule()).getApi(); + new GoogleAppEngineConfigurationModule()).getApi(); // common namespace for storing tweets. container = checkNotNull(props.getProperty(PROPERTY_TWEETSTORE_CONTAINER), @@ -92,7 +92,7 @@ public class GuiceServletConfig extends GuiceServletContextListener { name = builderClass.getSimpleName().replaceAll("BlobStoreContextBuilder", ""); constructor = builderClass.getConstructor(Properties.class); context = constructor.newInstance(props).withModules( - new GaeHttpCommandExecutorServiceModule()).buildContext(); + new GoogleAppEngineConfigurationModule()).buildContext(); } catch (Exception e) { throw new RuntimeException("error instantiating " + className, e); } diff --git a/extensions/gae/pom.xml b/extensions/gae/pom.xml index e9549147da..520a89c378 100644 --- a/extensions/gae/pom.xml +++ b/extensions/gae/pom.xml @@ -1,24 +1,23 @@ - + 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. + ==================================================================== + --> @@ -40,6 +39,16 @@ + + ${project.groupId} + jclouds-joda + ${project.version} + + + ${project.groupId} + jclouds-bouncycastle + ${project.version} + com.google.appengine appengine-api diff --git a/extensions/gae/src/main/java/org/jclouds/gae/config/GaeHttpCommandExecutorServiceModule.java b/extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java similarity index 73% rename from extensions/gae/src/main/java/org/jclouds/gae/config/GaeHttpCommandExecutorServiceModule.java rename to extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java index 7eaf41073b..eec7360fb7 100644 --- a/extensions/gae/src/main/java/org/jclouds/gae/config/GaeHttpCommandExecutorServiceModule.java +++ b/extensions/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java @@ -19,6 +19,10 @@ package org.jclouds.gae.config; import org.jclouds.concurrent.SingleThreaded; +import org.jclouds.concurrent.config.ConfiguresExecutorService; +import org.jclouds.concurrent.config.ExecutorServiceModule; +import org.jclouds.date.joda.config.JodaDateServiceModule; +import org.jclouds.encryption.bouncycastle.config.BouncyCastleEncryptionServiceModule; import org.jclouds.gae.GaeHttpCommandExecutorService; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.TransformingHttpCommandExecutorService; @@ -27,7 +31,7 @@ import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; import com.google.appengine.api.urlfetch.URLFetchService; import com.google.appengine.api.urlfetch.URLFetchServiceFactory; -import com.google.inject.AbstractModule; +import com.google.common.util.concurrent.Executors; import com.google.inject.Provides; /** @@ -36,11 +40,19 @@ import com.google.inject.Provides; * @author Adrian Cole */ @ConfiguresHttpCommandExecutorService +@ConfiguresExecutorService @SingleThreaded -public class GaeHttpCommandExecutorServiceModule extends AbstractModule { +public class GoogleAppEngineConfigurationModule extends ExecutorServiceModule { + + public GoogleAppEngineConfigurationModule() { + super(Executors.sameThreadExecutor()); + } @Override protected void configure() { + super.configure(); + install(new BouncyCastleEncryptionServiceModule()); + install(new JodaDateServiceModule()); bind(HttpCommandExecutorService.class).to(GaeHttpCommandExecutorService.class); bind(TransformingHttpCommandExecutorService.class).to( TransformingHttpCommandExecutorServiceImpl.class); @@ -50,5 +62,4 @@ public class GaeHttpCommandExecutorServiceModule extends AbstractModule { URLFetchService provideURLFetchService() { return URLFetchServiceFactory.getURLFetchService(); } - -} \ No newline at end of file +} diff --git a/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java b/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java index 4094e143ca..31e0fa8638 100644 --- a/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java +++ b/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java @@ -27,7 +27,7 @@ import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.jclouds.gae.config.GaeHttpCommandExecutorServiceModule; +import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; import org.jclouds.http.BaseHttpCommandExecutorServiceTest; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeTest; @@ -241,7 +241,7 @@ public class GaeHttpCommandExecutorServiceIntegrationTest extends } protected Module createConnectionModule() { - return new GaeHttpCommandExecutorServiceModule(); + return new GoogleAppEngineConfigurationModule(); } @Override diff --git a/extensions/gae/src/test/java/org/jclouds/gae/config/GaeHttpCommandExecutorServiceModuleTest.java b/extensions/gae/src/test/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModuleModuleTest.java similarity index 62% rename from extensions/gae/src/test/java/org/jclouds/gae/config/GaeHttpCommandExecutorServiceModuleTest.java rename to extensions/gae/src/test/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModuleModuleTest.java index fcbcfc106a..c0cae7aad1 100644 --- a/extensions/gae/src/test/java/org/jclouds/gae/config/GaeHttpCommandExecutorServiceModuleTest.java +++ b/extensions/gae/src/test/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModuleModuleTest.java @@ -18,11 +18,8 @@ */ package org.jclouds.gae.config; -import static com.google.common.util.concurrent.Executors.sameThreadExecutor; - import java.util.Properties; -import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.gae.GaeHttpCommandExecutorService; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.logging.Logger; @@ -34,29 +31,28 @@ import com.google.inject.Guice; import com.google.inject.Injector; /** - * Tests the ability to configure a {@link GaeHttpCommandExecutorService} + * Tests the ability to configure a {@link GoogleAppEngineConfigurationModule} * * @author Adrian Cole */ @Test -public class GaeHttpCommandExecutorServiceModuleTest { +public class GoogleAppEngineConfigurationModuleModuleTest { public void testConfigureBindsClient() { final Properties properties = new Properties(); - Injector i = Guice.createInjector(new ExecutorServiceModule(sameThreadExecutor()), - new GaeHttpCommandExecutorServiceModule() { - @Override - protected void configure() { - Jsr330.bindProperties(binder(), properties); - bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { - public Logger getLogger(String category) { - return Logger.NULL; - } - }); - super.configure(); - } - }); + Injector i = Guice.createInjector(new GoogleAppEngineConfigurationModule() { + @Override + protected void configure() { + Jsr330.bindProperties(binder(), properties); + bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() { + public Logger getLogger(String category) { + return Logger.NULL; + } + }); + super.configure(); + } + }); HttpCommandExecutorService client = i.getInstance(HttpCommandExecutorService.class); assert client instanceof GaeHttpCommandExecutorService; } diff --git a/extensions/joda/src/main/java/org/jclouds/date/joda/JodaDateService.java b/extensions/joda/src/main/java/org/jclouds/date/joda/JodaDateService.java index 749b4ca73f..f193b46c4a 100755 --- a/extensions/joda/src/main/java/org/jclouds/date/joda/JodaDateService.java +++ b/extensions/joda/src/main/java/org/jclouds/date/joda/JodaDateService.java @@ -20,6 +20,7 @@ package org.jclouds.date.joda; import java.util.Date; import java.util.Locale; +import java.util.regex.Pattern; import javax.inject.Singleton; @@ -100,10 +101,29 @@ public class JodaDateService implements DateService { } public final Date iso8601DateParse(String toParse) { + toParse = trimNanosToMillis(toParse); return iso8601DateFormatter.parseDateTime(toParse).toDate(); } + public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern + .compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]"); + + private String trimNanosToMillis(String toParse) { + if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches()) + toParse = toParse.substring(0, toParse.length() - 3) + 'Z'; + return toParse; + } + + public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00"); + + private String trimTZ(String toParse) { + if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches()) + toParse = toParse.substring(0, toParse.length() - 6) + 'Z'; + return toParse; + } + public final Date iso8601SecondsDateParse(String toParse) { + toParse = trimTZ(toParse); return iso8601SecondsDateFormatter.parseDateTime(toParse).toDate(); } } \ No newline at end of file