From ad82870b2842957a2433b8814c2f3776fd79e581 Mon Sep 17 00:00:00 2001 From: David Xia Date: Tue, 2 Oct 2018 18:34:07 -0400 Subject: [PATCH] Remove DockerDateFormat This library was originally using Java 7. Java 7 had `Date` objects with only millisecond resolution. This was a problem when translating timestamps with nanosecond precision from the Docker API to `Date`. This library is on Java 8 now which supports nanosecond resolution. This PR fixes the findbugs error here https://github.com/spotify/docker-client/pull/1068. See build logs https://travis-ci.org/spotify/docker-client/jobs/426781589. --- findbugs-exclude.xml | 6 -- .../docker/client/DockerDateFormat.java | 70 ----------------- .../docker/client/ObjectMapperProvider.java | 1 - .../docker/client/DockerDateFormatTest.java | 77 ------------------- 4 files changed, 154 deletions(-) delete mode 100644 src/main/java/com/spotify/docker/client/DockerDateFormat.java delete mode 100644 src/test/java/com/spotify/docker/client/DockerDateFormatTest.java diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml index 2277ec707..05279e545 100644 --- a/findbugs-exclude.xml +++ b/findbugs-exclude.xml @@ -5,10 +5,4 @@ - - - - - - \ No newline at end of file diff --git a/src/main/java/com/spotify/docker/client/DockerDateFormat.java b/src/main/java/com/spotify/docker/client/DockerDateFormat.java deleted file mode 100644 index c86fe9f86..000000000 --- a/src/main/java/com/spotify/docker/client/DockerDateFormat.java +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * -\-\- - * docker-client - * -- - * Copyright (C) 2016 Spotify AB - * -- - * 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 com.spotify.docker.client; - -import com.fasterxml.jackson.databind.util.StdDateFormat; - -import java.text.ParseException; -import java.util.Date; - -/** - * Docker returns timestamps with nanosecond precision - * (e.g. 2014-10-17T21:22:56.949763914Z), - * but {@link Date} only supports milliseconds. Creating a Date from the nanosecond timestamp - * results in the date being set to several days after what date should be. This class converts the - * timestamp from nanoseconds to milliseconds by removing the last six digits of the timestamp, so - * we can generate a Date with the correct value (albeit with less precision). - * - *

Note: a more complete solution would be to introduce a custom date type which can store the - * nanosecond value in an additional field, so users can access the complete value. Or just use Java - * 8 which has date objects with nanosecond support. - */ -public class DockerDateFormat extends StdDateFormat { - - private static final long serialVersionUID = 249048552876483658L; - - // either a literal Z or an offset like -04:00 or +1200 with an optional colon separator - private static final String TIMEZONE_PATTERN = "(Z|[+-]\\d{2}:?\\d{2})"; - - @Override - public Date parse(String source) throws ParseException { - // If the date has nanosecond precision (e.g. 2014-10-17T21:22:56.949763914Z), remove the last - // digits so we can create a Date object, which only support milliseconds. - // Docker doesn't always return nine digits for the fractional seconds part, - // so we need to be more flexible when trimming to milliseconds. - // Also allow for flexible timezone formats, either 'Z' for zulu/UTC or hour offsets. - // StdDateFormat has logic for handling these other timezones, but only if the time portion of - // the string matches hh:mm:ss or hh:mm:ss.SSS - if (source.matches(".+\\.\\d{4,9}" + TIMEZONE_PATTERN + "$")) { - source = source.replaceAll("(\\.\\d{3})\\d{1,6}" + TIMEZONE_PATTERN + "$", "$1$2"); - } - - return super.parse(source); - } - - @Override - @SuppressWarnings("CloneDoesntCallSuperClone") - public DockerDateFormat clone() { - // Normally clone should call super.clone(), but that works only if StdDateFormat calls - // super.clone(), which it does not. We must create a new instance and disable the warning. - return new DockerDateFormat(); - } -} diff --git a/src/main/java/com/spotify/docker/client/ObjectMapperProvider.java b/src/main/java/com/spotify/docker/client/ObjectMapperProvider.java index f882e6655..faa1acd50 100644 --- a/src/main/java/com/spotify/docker/client/ObjectMapperProvider.java +++ b/src/main/java/com/spotify/docker/client/ObjectMapperProvider.java @@ -75,7 +75,6 @@ public Object apply(final Object input) { OBJECT_MAPPER.registerModule(MODULE); OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); - OBJECT_MAPPER.setDateFormat(new DockerDateFormat()); } catch (Throwable t) { log.error("Failure during static initialization", t); throw t; diff --git a/src/test/java/com/spotify/docker/client/DockerDateFormatTest.java b/src/test/java/com/spotify/docker/client/DockerDateFormatTest.java deleted file mode 100644 index 317d4c039..000000000 --- a/src/test/java/com/spotify/docker/client/DockerDateFormatTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * -\-\- - * docker-client - * -- - * Copyright (C) 2016 Spotify AB - * -- - * 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 com.spotify.docker.client; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - -import com.fasterxml.jackson.databind.util.StdDateFormat; - -import java.util.Date; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.junit.Before; -import org.junit.Test; - -public class DockerDateFormatTest { - - private final DockerDateFormat dockerDateFormat = new DockerDateFormat(); - private final String millisecondDateString = "2015-09-18T17:44:28.145Z"; - private Date expected; - - @Before - public void setUp() throws Exception { - expected = new StdDateFormat().parse(millisecondDateString); - } - - /** - * Verify DockerDateFormat handles millisecond precision correctly. - */ - @Test - public void testHandlesMillisecondPrecision() throws Exception { - assertThat(dockerDateFormat.parse(millisecondDateString), equalTo(expected)); - } - - /** - * Verify DockerDateFormat converts nanosecond precision down to millisecond precision. - */ - @Test - public void testHandlesNanosecondPrecision() throws Exception { - assertThat(dockerDateFormat.parse("2015-09-18T17:44:28.145855389Z"), equalTo(expected)); - } - - /** - * Verify DockerDateFormat converts nanosecond precision with less than nine digits - * down to millisecond precision. - */ - @Test - public void testHandlesNanosecondWithLessThanNineDigits() throws Exception { - assertThat(dockerDateFormat.parse("2015-09-18T17:44:28.1458553Z"), equalTo(expected)); - } - - @Test - public void otherTimeZones() throws Exception { - final Date expected = - new DateTime(2016, 6, 3, 6, 57, 17, 478, DateTimeZone.forOffsetHours(-4)).toDate(); - assertThat(dockerDateFormat.parse("2016-06-03T06:57:17.4782869-04:00"), equalTo(expected)); - } -}