From 0ea1032d9070294016b09d15daf04193b4656165 Mon Sep 17 00:00:00 2001 From: Craig Bryant Date: Sun, 14 Feb 2016 12:10:03 -0700 Subject: [PATCH] Use SimpleDateFormat in thread safe construct This was seen in a monasca-api.log: ERROR [2016-02-13 17:18:41,546] monasca.common.middleware.TokenExceptionHandler: Http Client Exception java.lang.NumberFormatException: multiple points com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NumberFormatException: multiple points Search shows that this can be caused by using a SimpleDateFormat concurrently in two or more threads. SimpleDataFormat is not Thread Safe. Use ThreadLocal to access SimpleDateFormant safely Change-Id: Id12e8da8acc8b8a36be2504b55a219eef7293d44 --- .../monasca/common/middleware/HttpAuthClient.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/monasca-common-middleware/src/main/java/monasca/common/middleware/HttpAuthClient.java b/java/monasca-common-middleware/src/main/java/monasca/common/middleware/HttpAuthClient.java index 900127c4..efc18ab1 100644 --- a/java/monasca-common-middleware/src/main/java/monasca/common/middleware/HttpAuthClient.java +++ b/java/monasca-common-middleware/src/main/java/monasca/common/middleware/HttpAuthClient.java @@ -51,12 +51,8 @@ public class HttpAuthClient implements AuthClient { private static final int DELTA_TIME_IN_SEC = 30; private static final String APPLICATION_JSON = "application/json"; - private static SimpleDateFormat expiryFormat; - - static { - expiryFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - expiryFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - } + // SimpleDateFormat is not thread safe, so use ThreadLocal + private static ThreadLocal expiryFormat = new ThreadLocal<>(); private final Config appConfig = Config.getInstance(); @@ -328,11 +324,15 @@ public class HttpAuthClient implements AuthClient { private boolean isExpired(String expires) { Date tokenExpiryDate; + if (expiryFormat.get() == null) { + expiryFormat.set(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")); + expiryFormat.get().setTimeZone(TimeZone.getTimeZone("UTC")); + } try { // The date looks like: 2014-11-13T02:34:59.953729Z // SimpleDateFormat can't handle the microseconds so take them off final String tmp = expires.replaceAll("\\.[\\d]+Z", "Z"); - tokenExpiryDate = expiryFormat.parse(tmp); + tokenExpiryDate = expiryFormat.get().parse(tmp); } catch (ParseException e) { logger.warn("Failure parsing Admin Token expiration date: {}", e.getMessage()); return true;