[java-identity-provider] branch main updated: IDP-1733 - Metric output includes nanosecs, doesn't allow TZ adjustment

Scott Cantor cantor.2 at osu.edu
Wed Dec 30 16:54:53 UTC 2020


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=1c82eff0b2ab5390c75f97821bda4094771df5ba

The following commit(s) were added to refs/heads/main by this push:
       new  1c82eff0b IDP-1733 - Metric output includes nanosecs, doesn't allow TZ adjustment
1c82eff0b is described below

commit 1c82eff0b2ab5390c75f97821bda4094771df5ba
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Dec 30 11:54:49 2020 -0500

    IDP-1733 - Metric output includes nanosecs, doesn't allow TZ adjustment
    
    https://issues.shibboleth.net/jira/browse/IDP-1733
---
 .../shibboleth/idp/admin/impl/OutputMetrics.java   | 60 ++++++++++++++++++----
 .../shibboleth/idp/flows/admin/metrics-beans.xml   |  3 +-
 2 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
index 6eecf63ad..9358ac625 100644
--- a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
@@ -18,7 +18,10 @@
 package net.shibboleth.idp.admin.impl;
 
 import java.io.IOException;
-import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -49,8 +52,11 @@ import com.codahale.metrics.Metric;
 import com.codahale.metrics.MetricFilter;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.json.MetricsModule;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.util.JSONPObject;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 
@@ -71,9 +77,6 @@ public class OutputMetrics extends AbstractProfileAction {
     /** Flow variable indicating ID of metric or group of metrics to output. */
     @Nonnull @NotEmpty public static final String METRIC_ID = "metricId";
     
-    /** Default date/time format string. */
-    @Nonnull @NotEmpty public static final String DEFAULT_DT_FORMAT = "YYYY-MM-dd'T'HH:mm:ss.SSSZZ";
-    
     /** Class logger. */
     @Nonnull private Logger log = LoggerFactory.getLogger(OutputMetrics.class);
     
@@ -89,8 +92,11 @@ public class OutputMetrics extends AbstractProfileAction {
     /** Name of JSONP callback function, if any. */
     @Nullable private String jsonpCallbackName;
 
-    /** Formatting string for {@link SimpleDateFormat} fields. */
-    @Nullable private String dateTimeFormat;
+    /** Formatter for date/time fields. */
+    @Nonnull private DateTimeFormatter dateTimeFormatter;
+
+    /** Convert date/time fields to default time zone. */
+    private boolean useDefaultTimeZone;
 
     /** Map of custom metric groups to filters. */
     @Nonnull @NonnullElements private Map<String,MetricFilter> metricFilterMap;
@@ -101,6 +107,7 @@ public class OutputMetrics extends AbstractProfileAction {
     /** Constructor. */
     public OutputMetrics() {
         metricFilterMap = Collections.emptyMap();
+        dateTimeFormatter = DateTimeFormatter.ISO_INSTANT;
     }
 
     /**
@@ -148,14 +155,29 @@ public class OutputMetrics extends AbstractProfileAction {
     }
     
     /**
-     * Set the formatting string to apply when writing date/time fields.
+     * Set the formatting string to apply when extracting date/time fields.
      * 
      * @param format formatting string
      */
     public void setDateTimeFormat(@Nullable @NotEmpty final String format) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
-        dateTimeFormat = StringSupport.trimOrNull(format);
+        if (format != null) {
+            dateTimeFormatter = DateTimeFormatter.ofPattern(StringSupport.trimOrNull(format));
+        }
+    }
+    
+    /**
+     * Convert date/time fields to default time zone.
+     * 
+     * @param flag flag to set
+     * 
+     * @since 4.1.0
+     */
+    public void setUseDefaultTimeZone(final boolean flag) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        useDefaultTimeZone = flag;
     }
     
     /**
@@ -184,6 +206,12 @@ public class OutputMetrics extends AbstractProfileAction {
         if (metricRegistry == null) {
             throw new ComponentInitializationException("MetricRegistry cannot be null");
         }
+        
+        if (useDefaultTimeZone) {
+            dateTimeFormatter = dateTimeFormatter.withZone(ZoneId.systemDefault());
+        } else {
+            dateTimeFormatter = dateTimeFormatter.withZone(ZoneOffset.UTC);
+        }
     }
 
     /** {@inheritDoc} */
@@ -254,8 +282,20 @@ public class OutputMetrics extends AbstractProfileAction {
             
             final ObjectMapper mapper = new ObjectMapper().registerModule(
                     new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, true, filter));
-            mapper.registerModule(new JavaTimeModule());
-            mapper.setDateFormat(new SimpleDateFormat(dateTimeFormat != null ? dateTimeFormat : DEFAULT_DT_FORMAT));
+
+            // The default Instant serializer cannot leverage a custom formatter. Seriously.
+            final JavaTimeModule javatime = new JavaTimeModule();
+            javatime.addSerializer(Instant.class, new JsonSerializer<Instant>() {
+                public void serialize(final Instant value, final JsonGenerator gen,
+                        final SerializerProvider serializers) throws IOException {
+                    gen.writeString(dateTimeFormatter.format(value));
+                }
+            });
+            
+            mapper.registerModule(javatime);
+            // These don't do much of anything, except the first one I think.
+            mapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
+            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
             mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
             
             if (jsonpCallbackName != null) {
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/metrics-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/metrics-beans.xml
index 809c564be..46e3d9fb5 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/metrics-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/metrics-beans.xml
@@ -37,7 +37,8 @@
         p:metricFilterMap-ref="shibboleth.metrics.MetricGroups"
         p:allowedOrigin="#{getObject('shibboleth.metrics.AllowedOrigin')}"
         p:JSONPCallbackName="#{getObject('shibboleth.metrics.JSONPCallback')}"
-        p:dateTimeFormat="#{getObject('shibboleth.AuditDateTimeFormat')}" />
+        p:dateTimeFormat="#{getObject('shibboleth.AuditDateTimeFormat')}"
+        p:useDefaultTimeZone="#{getObject('shibboleth.AuditDefaultTimeZone') ?: false}" />
         
     <bean id="RecordResponseComplete" class="net.shibboleth.idp.profile.impl.RecordResponseComplete" scope="prototype" />
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list