mirror of https://github.com/apache/jclouds.git
Issue 647: DateCodec impl delegates to DateService
This commit is contained in:
parent
cd9c830c5a
commit
2637a4b6e9
|
@ -95,6 +95,7 @@ import org.jclouds.http.HttpResponseException;
|
|||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.ContentMetadataCodec;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
@ -124,6 +125,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
protected final DateService dateService;
|
||||
protected final Crypto crypto;
|
||||
protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
|
||||
protected final ContentMetadataCodec contentMetadataCodec;
|
||||
protected final IfDirectoryReturnNameStrategy ifDirectoryReturnName;
|
||||
protected final Factory blobFactory;
|
||||
protected final FilesystemStorageStrategy storageStrategy;
|
||||
|
@ -132,6 +134,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
protected FilesystemAsyncBlobStore(BlobStoreContext context,
|
||||
DateService dateService, Crypto crypto,
|
||||
HttpGetOptionsListToGetOptions httpGetOptionsConverter,
|
||||
ContentMetadataCodec contentMetadataCodec,
|
||||
IfDirectoryReturnNameStrategy ifDirectoryReturnName,
|
||||
BlobUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
|
@ -143,6 +146,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
this.dateService = dateService;
|
||||
this.crypto = crypto;
|
||||
this.httpGetOptionsConverter = httpGetOptionsConverter;
|
||||
this.contentMetadataCodec = contentMetadataCodec;
|
||||
this.ifDirectoryReturnName = ifDirectoryReturnName;
|
||||
this.storageStrategy = checkNotNull(storageStrategy, "Storage strategy");
|
||||
}
|
||||
|
@ -475,7 +479,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
private void copyPayloadHeadersToBlob(Payload payload, Blob blob) {
|
||||
blob.getAllHeaders().putAll(HttpUtils.getContentHeadersFromMetadata(payload.getContentMetadata()));
|
||||
blob.getAllHeaders().putAll(contentMetadataCodec.toHeaders(payload.getContentMetadata()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -114,6 +114,21 @@ public class NovaEC2ParserModule extends AbstractModule {
|
|||
if (Objects.equal("-", toParse)) return null;
|
||||
return delegate.iso8601SecondsDateParse(toParse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String rfc1123DateFormat(Date date) {
|
||||
return delegate.rfc1123DateFormat(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String rfc1123DateFormat() {
|
||||
return delegate.rfc1123DateFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date rfc1123DateParse(String toParse) {
|
||||
return delegate.rfc1123DateParse(toParse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package org.jclouds.date;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateCodecFactory;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
|
||||
/**
|
||||
* Codecs for converting from Date->String and vice versa.
|
||||
*
|
||||
* @author aled
|
||||
*/
|
||||
@ImplementedBy(SimpleDateCodecFactory.class)
|
||||
public interface DateCodecFactory {
|
||||
|
||||
public DateCodec rfc1123();
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package org.jclouds.date;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DateCodecs {
|
||||
|
||||
// See http://stackoverflow.com/questions/10584647/simpledateformat-parse-is-one-hour-out-using-rfc-1123-gmt-in-summer
|
||||
// for why not using "zzz"
|
||||
public final static String RFC1123_DATE_PATTERN = "EEE, dd MMM yyyyy HH:mm:ss Z";
|
||||
|
||||
/*
|
||||
* Use default Java Date/SimpleDateFormat classes for date manipulation, but be *very* careful to
|
||||
* guard against the lack of thread safety.
|
||||
*/
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat rfc1123SimpleDateFormat = new SimpleDateFormat(RFC1123_DATE_PATTERN, Locale.US);
|
||||
|
||||
public static DateCodec rfc1123() {
|
||||
return new SimpleDateCodec(rfc1123SimpleDateFormat);
|
||||
}
|
||||
|
||||
private static class SimpleDateCodec implements DateCodec {
|
||||
|
||||
private final SimpleDateFormat dateFormat;
|
||||
|
||||
SimpleDateCodec(SimpleDateFormat dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date toDate(String date) throws ParseException {
|
||||
synchronized (dateFormat) {
|
||||
return dateFormat.parse(date);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Date date) {
|
||||
synchronized (dateFormat) {
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,4 +60,10 @@ public interface DateService {
|
|||
|
||||
Date iso8601SecondsDateParse(String toParse);
|
||||
|
||||
String rfc1123DateFormat(Date date);
|
||||
|
||||
String rfc1123DateFormat();
|
||||
|
||||
Date rfc1123DateParse(String toParse);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package org.jclouds.date.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.date.DateCodec;
|
||||
import org.jclouds.date.DateCodecFactory;
|
||||
import org.jclouds.date.DateService;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class SimpleDateCodecFactory implements DateCodecFactory {
|
||||
|
||||
private final DateService dateService;
|
||||
|
||||
private volatile DateCodec rfc1123Codec;
|
||||
|
||||
@Inject
|
||||
public SimpleDateCodecFactory(final DateService dateService) {
|
||||
this.dateService = checkNotNull(dateService, "dateService");
|
||||
}
|
||||
|
||||
public DateCodec rfc1123() {
|
||||
if (rfc1123Codec == null) {
|
||||
rfc1123Codec = new DateCodec() {
|
||||
@Override
|
||||
public Date toDate(String date) throws ParseException {
|
||||
return dateService.rfc1123DateParse(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Date date) {
|
||||
return dateService.rfc1123DateFormat(date);
|
||||
}
|
||||
};
|
||||
}
|
||||
return rfc1123Codec;
|
||||
}
|
||||
}
|
|
@ -51,6 +51,11 @@ public class SimpleDateFormatDateService implements DateService {
|
|||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
||||
|
||||
// See http://stackoverflow.com/questions/10584647/simpledateformat-parse-is-one-hour-out-using-rfc-1123-gmt-in-summer
|
||||
// for why not using "zzz"
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat rfc1123SimpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss Z", Locale.US);
|
||||
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US);
|
||||
|
||||
|
@ -180,4 +185,26 @@ public class SimpleDateFormatDateService implements DateService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String rfc1123DateFormat(Date date) {
|
||||
synchronized (rfc1123SimpleDateFormat) {
|
||||
return rfc1123SimpleDateFormat.format(date);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String rfc1123DateFormat() {
|
||||
return rfc1123DateFormat(new Date());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Date rfc1123DateParse(String toParse) {
|
||||
synchronized (rfc1123SimpleDateFormat) {
|
||||
try {
|
||||
return rfc1123SimpleDateFormat.parse(toParse);
|
||||
} catch (ParseException pe) {
|
||||
throw new RuntimeException("Error parsing data at " + pe.getErrorOffset(), pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.date.DateCodec;
|
||||
import org.jclouds.date.DateCodecs;
|
||||
import org.jclouds.date.DateCodecFactory;
|
||||
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
|
@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMultimap;
|
|||
import com.google.common.collect.ImmutableMultimap.Builder;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.ImplementedBy;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@ImplementedBy(DefaultContentMetadataCodec.class)
|
||||
public interface ContentMetadataCodec {
|
||||
|
@ -53,7 +54,12 @@ public interface ContentMetadataCodec {
|
|||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final DateCodec httpExpiresDateCodec = DateCodecs.rfc1123();
|
||||
private final DateCodec httpExpiresDateCodec;
|
||||
|
||||
@Inject
|
||||
public DefaultContentMetadataCodec(DateCodecFactory dateCodecs) {
|
||||
httpExpiresDateCodec = dateCodecs.rfc1123();
|
||||
}
|
||||
|
||||
protected DateCodec getExpiresDateCodec() {
|
||||
return httpExpiresDateCodec;
|
||||
|
|
|
@ -34,6 +34,8 @@ import javax.net.ssl.SSLContext;
|
|||
import javax.net.ssl.SSLSession;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateCodecFactory;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.http.BaseJettyTest;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -113,7 +115,8 @@ public class BackoffLimitedRetryHandlerTest {
|
|||
ExecutorService execService = Executors.newCachedThreadPool();
|
||||
BackoffLimitedRetryHandler backoff = new BackoffLimitedRetryHandler();
|
||||
HttpUtils utils = new HttpUtils(0, 500, 1, 1);
|
||||
ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec();
|
||||
ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec(
|
||||
new SimpleDateCodecFactory(new SimpleDateFormatDateService()));
|
||||
RedirectionRetryHandler retry = new RedirectionRetryHandler(uriBuilderProvider, backoff);
|
||||
JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService(utils,
|
||||
contentMetadataCodec, execService,
|
||||
|
|
|
@ -49,6 +49,8 @@ import org.jclouds.apis.ApiMetadata;
|
|||
import org.jclouds.concurrent.MoreExecutors;
|
||||
import org.jclouds.concurrent.SingleThreaded;
|
||||
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
||||
import org.jclouds.date.internal.SimpleDateCodecFactory;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.http.HttpCommandExecutorService;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -60,10 +62,10 @@ import org.jclouds.http.handlers.DelegatingRetryHandler;
|
|||
import org.jclouds.http.internal.BaseHttpCommandExecutorService;
|
||||
import org.jclouds.http.internal.HttpWire;
|
||||
import org.jclouds.io.ContentMetadataCodec;
|
||||
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
|
||||
import org.jclouds.io.CopyInputStreamInputSupplierMap;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
|
||||
import org.jclouds.logging.config.NullLoggingModule;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.RestApiMetadata;
|
||||
|
@ -120,7 +122,8 @@ public abstract class BaseRestClientExpectTest<S> {
|
|||
|
||||
protected String provider = "mock";
|
||||
|
||||
protected ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec();
|
||||
protected ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec(
|
||||
new SimpleDateCodecFactory(new SimpleDateFormatDateService()));
|
||||
|
||||
/**
|
||||
* Override this to supply alternative bindings for use in the test. This is commonly used to
|
||||
|
|
|
@ -32,6 +32,8 @@ import javax.ws.rs.HttpMethod;
|
|||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.internal.SimpleDateCodecFactory;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.encryption.internal.JCECrypto;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
@ -72,7 +74,9 @@ public class ConvertToGaeRequestTest {
|
|||
@BeforeTest
|
||||
void setupClient() throws MalformedURLException {
|
||||
endPoint = URI.create("http://localhost:80/foo");
|
||||
req = new ConvertToGaeRequest(new HttpUtils(0, 0, 0, 0), new DefaultContentMetadataCodec());
|
||||
req = new ConvertToGaeRequest(new HttpUtils(0, 0, 0, 0), new DefaultContentMetadataCodec(
|
||||
new SimpleDateCodecFactory(new SimpleDateFormatDateService())));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -34,6 +34,8 @@ import java.util.List;
|
|||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.internal.SimpleDateCodecFactory;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.encryption.internal.JCECrypto;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
|
||||
|
@ -68,7 +70,8 @@ public class ConvertToJcloudsResponseTest {
|
|||
@BeforeTest
|
||||
void setupClient() throws MalformedURLException {
|
||||
endPoint = URI.create("http://localhost:80/foo");
|
||||
req = new ConvertToJcloudsResponse(new DefaultContentMetadataCodec());
|
||||
req = new ConvertToJcloudsResponse(new DefaultContentMetadataCodec(
|
||||
new SimpleDateCodecFactory(new SimpleDateFormatDateService())));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -53,6 +53,9 @@ public class JodaDateService implements DateService {
|
|||
private static final DateTimeFormatter iso8601DateFormatter = DateTimeFormat.forPattern(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSZ").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT"));
|
||||
|
||||
private static final DateTimeFormatter rfc1123DateFormat = DateTimeFormat.forPattern(
|
||||
"EEE, dd MMM yyyyy HH:mm:ss Z").withLocale(Locale.US).withZone(DateTimeZone.forID("GMT"));
|
||||
|
||||
public final Date fromSeconds(long seconds) {
|
||||
return new Date(seconds * 1000);
|
||||
}
|
||||
|
@ -124,4 +127,19 @@ public class JodaDateService implements DateService {
|
|||
toParse += tz;
|
||||
return iso8601SecondsDateFormatter.parseDateTime(toParse).toDate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String rfc1123DateFormat(Date dateTime) {
|
||||
return rfc1123DateFormat.print(new DateTime(dateTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String rfc1123DateFormat() {
|
||||
return rfc1123DateFormat(new Date());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Date rfc1123DateParse(String toParse) {
|
||||
return rfc1123DateFormat.parseDateTime(toParse).toDate();
|
||||
}
|
||||
}
|
|
@ -23,27 +23,18 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.domain.Location;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.date.DateCodec;
|
||||
import org.jclouds.date.DateCodecs;
|
||||
import org.jclouds.http.HttpCommandExecutorService;
|
||||
import org.jclouds.http.TransformingHttpCommandExecutorService;
|
||||
import org.jclouds.http.TransformingHttpCommandExecutorServiceImpl;
|
||||
import org.jclouds.http.config.SSLModule;
|
||||
import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService;
|
||||
import org.jclouds.date.internal.SimpleDateCodecFactory;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.io.ContentMetadataCodec;
|
||||
import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
|
||||
import org.jclouds.s3.blobstore.integration.S3ContainerLiveTest;
|
||||
|
@ -51,13 +42,10 @@ import org.jclouds.util.Strings2;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -89,12 +77,12 @@ public class AWSS3ContainerLiveTest extends S3ContainerLiveTest {
|
|||
@Test(groups = { "live" })
|
||||
public void testCreateBlobWithMalformedExpiry() throws InterruptedException, MalformedURLException, IOException {
|
||||
// Create a blob that has a malformed Expires value; requires overriding the ContentMetadataCodec in Guice...
|
||||
final ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec() {
|
||||
final ContentMetadataCodec contentMetadataCodec = new DefaultContentMetadataCodec(new SimpleDateCodecFactory(new SimpleDateFormatDateService())) {
|
||||
@Override
|
||||
protected DateCodec getExpiresDateCodec() {
|
||||
return new DateCodec() {
|
||||
@Override public Date toDate(String date) throws ParseException {
|
||||
return DateCodecs.rfc1123().toDate(date);
|
||||
return new Date();
|
||||
}
|
||||
@Override public String toString(Date date) {
|
||||
return "wrong";
|
||||
|
|
Loading…
Reference in New Issue