You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streams.apache.org by sb...@apache.org on 2020/08/21 17:52:01 UTC

[streams] 01/04: STREAMS-671 flink twitter examples output files do not contain date-time fields

This is an automated email from the ASF dual-hosted git repository.

sblackmon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/streams.git

commit c176d09435b619e4c1e8b6d66e2d10b24adc68e3
Author: sblackmon <sb...@apache.org>
AuthorDate: Wed Aug 12 11:07:16 2020 -0500

    STREAMS-671 flink twitter examples output files do not contain date-time fields
    
    switch the twitter pojos to use java.util.Date and build them without additionalProperties maps,
---
 streams-contrib/streams-provider-twitter/pom.xml   | 42 +++++++++--
 .../org/apache/streams/twitter/api/Twitter.java    |  5 +-
 .../streams/twitter/converter/TwitterDateSwap.java | 51 +++++++++++++
 .../converter/util/TwitterActivityUtil.java        |  5 +-
 .../flink-twitter-collection/pom.xml               | 83 ++++++++++++++++------
 .../TwitterFollowingPipelineConfiguration.json     |  6 +-
 .../TwitterPostsPipelineConfiguration.json         |  6 +-
 .../TwitterSpritzerPipelineConfiguration.json      |  6 +-
 ...witterUserInformationPipelineConfiguration.json |  6 +-
 .../java/org/apache/streams/juneau/DateSwap.java   | 69 ++++++++++++++++++
 10 files changed, 238 insertions(+), 41 deletions(-)

diff --git a/streams-contrib/streams-provider-twitter/pom.xml b/streams-contrib/streams-provider-twitter/pom.xml
index 40685a4..01ef834 100644
--- a/streams-contrib/streams-provider-twitter/pom.xml
+++ b/streams-contrib/streams-provider-twitter/pom.xml
@@ -31,6 +31,7 @@
 
     <properties>
         <skipITs>true</skipITs>
+        <jsonschema2pojo.plugin.version>1.0.2</jsonschema2pojo.plugin.version>
     </properties>
 
     <dependencies>
@@ -147,15 +148,46 @@
         </testResources>
         <plugins>
             <plugin>
-                <groupId>org.apache.streams.plugins</groupId>
-                <artifactId>streams-plugin-pojo</artifactId>
-                <version>${project.version}</version>
+                <groupId>org.jsonschema2pojo</groupId>
+                <artifactId>jsonschema2pojo-maven-plugin</artifactId>
+                <version>${jsonschema2pojo.plugin.version}</version>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.streams</groupId>
+                        <artifactId>streams-persist-hdfs</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.apache.streams.plugins</groupId>
+                        <artifactId>streams-plugin-pojo</artifactId>
+                        <version>${streams.version}</version>
+                    </dependency>
+                </dependencies>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
                 <configuration>
+                    <annotationStyle>jackson2</annotationStyle>
+                    <customAnnotator>org.apache.streams.plugins.JuneauPojoAnnotator</customAnnotator>
+                    <generateBuilders>true</generateBuilders>
+                    <includeAdditionalProperties>false</includeAdditionalProperties>
+                    <includeDynamicAccessors>true</includeDynamicAccessors>
+                    <includeHashcodeAndEquals>true</includeHashcodeAndEquals>
+                    <outputDirectory>${project.basedir}/target/generated-sources/pojo</outputDirectory>
+                    <propertyWordDelimiters></propertyWordDelimiters>
+                    <removeOldOutput>true</removeOldOutput>
+                    <serializable>true</serializable>
                     <sourcePaths>
                         <sourcePath>${project.basedir}/src/main/jsonschema</sourcePath>
                     </sourcePaths>
-                    <targetDirectory>${project.basedir}/target/generated-sources/pojo</targetDirectory>
-                    <targetPackage>org.apache.streams.twitter.pojo</targetPackage>
+                    <useDoubleNumbers>true</useDoubleNumbers>
+                    <useLongIntegers>true</useLongIntegers>
+                    <useJodaDates>false</useJodaDates>
                 </configuration>
             </plugin>
             <plugin>
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
index ddb3d28..ebb9c64 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
@@ -21,6 +21,7 @@ package org.apache.streams.twitter.api;
 import org.apache.streams.config.ComponentConfigurator;
 import org.apache.streams.jackson.StreamsJacksonMapper;
 import org.apache.streams.twitter.config.TwitterConfiguration;
+import org.apache.streams.twitter.converter.TwitterDateSwap;
 import org.apache.streams.twitter.converter.TwitterDateTimeFormat;
 import org.apache.streams.twitter.converter.TwitterJodaDateSwap;
 import org.apache.streams.twitter.pojo.DirectMessage;
@@ -125,11 +126,11 @@ public class Twitter implements
       .parser(
         JsonParser.DEFAULT.builder()
           .ignoreUnknownBeanProperties(true)
-          .pojoSwaps(TwitterJodaDateSwap.class)
+          .pojoSwaps(TwitterJodaDateSwap.class, TwitterDateSwap.class)
           .build())
       .serializer(
         JsonSerializer.DEFAULT.builder()
-          .pojoSwaps(TwitterJodaDateSwap.class)
+          .pojoSwaps(TwitterJodaDateSwap.class, TwitterDateSwap.class)
           .trimEmptyCollections(true)
           .trimEmptyMaps(true)
           .build())
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java
new file mode 100644
index 0000000..f4d5705
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/TwitterDateSwap.java
@@ -0,0 +1,51 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+*
+*   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 org.apache.streams.twitter.converter;
+
+import org.apache.juneau.BeanSession;
+import org.apache.juneau.ClassMeta;
+import org.apache.juneau.parser.ParseException;
+import org.apache.juneau.transform.StringSwap;
+import org.apache.streams.data.util.RFC3339Utils;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+/**
+ * Transforms {@link Date} to {@link String Strings}.
+ */
+
+public class TwitterDateSwap extends StringSwap<Date> {
+
+  DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(TwitterDateTimeFormat.TWITTER_FORMAT);
+
+  @Override /* PojoSwap */
+  public String swap(BeanSession session, Date o) {
+    return ZonedDateTime.ofInstant(o.toInstant(), ZoneOffset.UTC).format(dateTimeFormatter);
+  }
+
+  @Override /* PojoSwap */
+  public Date unswap(BeanSession session, String s, ClassMeta<?> hint) {
+    return Date.from(LocalDateTime.parse(s, dateTimeFormatter).atZone(ZoneOffset.UTC).toInstant());
+  }
+
+}
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/util/TwitterActivityUtil.java b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/util/TwitterActivityUtil.java
index 6f92aa3..d8fffcc 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/util/TwitterActivityUtil.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/converter/util/TwitterActivityUtil.java
@@ -41,6 +41,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,7 +87,7 @@ public class TwitterActivityUtil {
       throw new ActivityConversionException("Unable to determine activity id");
     }
     try {
-      activity.setPublished(tweet.getCreatedAt());
+      activity.setPublished(new DateTime(tweet.getCreatedAt()));
     } catch ( Exception ex ) {
       throw new ActivityConversionException("Unable to determine publishedDate", ex);
     }
@@ -323,7 +324,7 @@ public class TwitterActivityUtil {
 
     Map<String, Object> likes = new HashMap<>();
     likes.put("perspectival", tweet.getFavorited());
-    likes.put("count", tweet.getAdditionalProperties().get("favorite_count"));
+    likes.put("count", tweet.getFavoriteCount());
 
     extensions.put("likes", likes);
 
diff --git a/streams-examples/streams-examples-flink/flink-twitter-collection/pom.xml b/streams-examples/streams-examples-flink/flink-twitter-collection/pom.xml
index 1e2de10..467536b 100644
--- a/streams-examples/streams-examples-flink/flink-twitter-collection/pom.xml
+++ b/streams-examples/streams-examples-flink/flink-twitter-collection/pom.xml
@@ -32,14 +32,16 @@
     <description>Collects twitter documents using flink.</description>
 
     <properties>
-        <testng.version>6.9.10</testng.version>
         <hdfs.version>2.7.0</hdfs.version>
         <flink.version>1.11.1</flink.version>
+        <testng.version>6.9.10</testng.version>
         <scala.version>2.11.12</scala.version>
         <scala.binary.version>2.11</scala.binary.version>
         <scalapc.version>1.1.0</scalapc.version>
         <scalatest.version>3.0.0</scalatest.version>
         <scalaxml.version>1.1.0</scalaxml.version>
+
+        <jsonschema2pojo.plugin.version>1.0.2</jsonschema2pojo.plugin.version>
     </properties>
 
     <dependencies>
@@ -394,22 +396,9 @@
                 </executions>
             </plugin>
             <plugin>
-                <groupId>org.apache.streams.plugins</groupId>
-                <artifactId>streams-plugin-pojo</artifactId>
-                <configuration>
-                    <sourcePaths>
-                        <sourcePath>${project.basedir}/src/main/jsonschema</sourcePath>
-                    </sourcePaths>
-                    <targetDirectory>${project.basedir}/target/generated-sources/pojo</targetDirectory>
-                    <targetPackage>org.apache.streams.examples.flink.twitter</targetPackage>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>generate-sources</goal>
-                        </goals>
-                    </execution>
-                </executions>
+                <groupId>org.jsonschema2pojo</groupId>
+                <artifactId>jsonschema2pojo-maven-plugin</artifactId>
+                <version>${jsonschema2pojo.plugin.version}</version>
                 <dependencies>
                     <dependency>
                         <groupId>org.apache.streams</groupId>
@@ -417,12 +406,66 @@
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
-                        <groupId>org.apache.streams</groupId>
-                        <artifactId>streams-provider-twitter</artifactId>
-                        <version>${project.version}</version>
+                        <groupId>org.apache.streams.plugins</groupId>
+                        <artifactId>streams-plugin-pojo</artifactId>
+                        <version>${streams.version}</version>
                     </dependency>
                 </dependencies>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <annotationStyle>jackson2</annotationStyle>
+                    <customAnnotator>org.apache.streams.plugins.JuneauPojoAnnotator</customAnnotator>
+                    <generateBuilders>true</generateBuilders>
+                    <includeAdditionalProperties>false</includeAdditionalProperties>
+                    <includeDynamicAccessors>true</includeDynamicAccessors>
+                    <includeHashcodeAndEquals>true</includeHashcodeAndEquals>
+                    <outputDirectory>${project.basedir}/target/generated-sources/pojo</outputDirectory>
+                    <propertyWordDelimiters></propertyWordDelimiters>
+                    <removeOldOutput>true</removeOldOutput>
+                    <serializable>true</serializable>
+                    <sourcePaths>
+                        <sourcePath>${project.basedir}/src/main/jsonschema</sourcePath>
+<!--                        <sourcePath>${project.basedir}/../../../streams-contrib/streams-provider-twitter/src/main/jsonschema</sourcePath>-->
+                    </sourcePaths>
+                    <useDoubleNumbers>true</useDoubleNumbers>
+                    <useLongIntegers>true</useLongIntegers>
+                    <useJodaDates>false</useJodaDates>
+                </configuration>
             </plugin>
+<!--            <plugin>-->
+<!--                <groupId>org.apache.streams.plugins</groupId>-->
+<!--                <artifactId>streams-plugin-pojo</artifactId>-->
+<!--                <configuration>-->
+<!--                    <targetDirectory>${project.basedir}/target/generated-sources/pojo</targetDirectory>-->
+<!--                    <targetPackage>org.apache.streams.examples.flink.twitter</targetPackage>-->
+<!--                </configuration>-->
+<!--                <executions>-->
+<!--                    <execution>-->
+<!--                        <goals>-->
+<!--                            <goal>generate-sources</goal>-->
+<!--                        </goals>-->
+<!--                    </execution>-->
+<!--                </executions>-->
+<!--                <dependencies>-->
+<!--                    <dependency>-->
+<!--                        <groupId>org.apache.streams</groupId>-->
+<!--                        <artifactId>streams-persist-hdfs</artifactId>-->
+<!--                        <version>${project.version}</version>-->
+<!--                    </dependency>-->
+<!--                    <dependency>-->
+<!--                        <groupId>org.apache.streams</groupId>-->
+<!--                        <artifactId>streams-provider-twitter</artifactId>-->
+<!--                        <version>${project.version}</version>-->
+<!--                    </dependency>-->
+<!--                </dependencies>-->
+<!--            </plugin>-->
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>build-helper-maven-plugin</artifactId>
diff --git a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterFollowingPipelineConfiguration.json b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterFollowingPipelineConfiguration.json
index bc56a0a..6f0bd54 100644
--- a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterFollowingPipelineConfiguration.json
+++ b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterFollowingPipelineConfiguration.json
@@ -13,15 +13,15 @@
   "properties": {
     "twitter": {
       "type": "object",
-      "javaType": "org.apache.streams.twitter.config.TwitterFollowingConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/config/TwitterFollowingConfiguration.json"
     },
     "source": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsReaderConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsReaderConfiguration.json"
     },
     "destination": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsWriterConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsWriterConfiguration.json"
     },
     "providerWaitMs": {
       "type": "integer"
diff --git a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterPostsPipelineConfiguration.json b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterPostsPipelineConfiguration.json
index 892c615..32ba3c0 100644
--- a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterPostsPipelineConfiguration.json
+++ b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterPostsPipelineConfiguration.json
@@ -13,15 +13,15 @@
   "properties": {
     "twitter": {
       "type": "object",
-      "javaType": "org.apache.streams.twitter.config.TwitterTimelineProviderConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/config/TwitterTimelineProviderConfiguration.json"
     },
     "source": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsReaderConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsReaderConfiguration.json"
     },
     "destination": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsWriterConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsWriterConfiguration.json"
     }
   }
 }
\ No newline at end of file
diff --git a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterSpritzerPipelineConfiguration.json b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterSpritzerPipelineConfiguration.json
index fe0cfbb..612d905 100644
--- a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterSpritzerPipelineConfiguration.json
+++ b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterSpritzerPipelineConfiguration.json
@@ -13,15 +13,15 @@
   "properties": {
     "twitter": {
       "type": "object",
-      "javaType": "org.apache.streams.twitter.config.TwitterStreamConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/config/TwitterStreamConfiguration.json"
     },
     "source": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsReaderConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsReaderConfiguration.json"
     },
     "destination": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsWriterConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsWriterConfiguration.json"
     }
   }
 }
\ No newline at end of file
diff --git a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterUserInformationPipelineConfiguration.json b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterUserInformationPipelineConfiguration.json
index ba3b5fc..ea8f505 100644
--- a/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterUserInformationPipelineConfiguration.json
+++ b/streams-examples/streams-examples-flink/flink-twitter-collection/src/main/jsonschema/TwitterUserInformationPipelineConfiguration.json
@@ -13,15 +13,15 @@
   "properties": {
     "twitter": {
       "type": "object",
-      "javaType": "org.apache.streams.twitter.config.TwitterUserInformationConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/config/TwitterUserInformationConfiguration.json"
     },
     "source": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsReaderConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsReaderConfiguration.json"
     },
     "destination": {
       "type": "object",
-      "javaType": "org.apache.streams.hdfs.HdfsWriterConfiguration"
+      "$ref": "../../../../../../streams-contrib/streams-persist-hdfs/src/main/jsonschema/org/apache/streams/hdfs/HdfsWriterConfiguration.json"
     }
   }
 }
\ No newline at end of file
diff --git a/streams-pojo/src/main/java/org/apache/streams/juneau/DateSwap.java b/streams-pojo/src/main/java/org/apache/streams/juneau/DateSwap.java
new file mode 100644
index 0000000..7e980f2
--- /dev/null
+++ b/streams-pojo/src/main/java/org/apache/streams/juneau/DateSwap.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ *
+ *   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 org.apache.streams.juneau;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.juneau.BeanSession;
+import org.apache.juneau.ClassMeta;
+import org.apache.juneau.parser.ParseException;
+import org.apache.juneau.transform.StringSwap;
+import org.apache.streams.data.util.RFC3339Utils;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+/**
+ * Transforms {@link Date} to {@link String Strings}.
+ */
+public class DateSwap extends StringSwap<Date> {
+
+  DateTimeFormatter dateTimeFormatter;
+
+  /**
+   * Constructor.
+   */
+  public DateSwap() {
+    dateTimeFormatter = DateTimeFormatter.ISO_INSTANT;
+  }
+
+  @Override /* PojoSwap */
+  public String swap(BeanSession session, Date o) {
+    DateTimeFormatter dateTimeFormatter = this.dateTimeFormatter;
+    if( StringUtils.isNotBlank(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()))) {
+      dateTimeFormatter = DateTimeFormatter.ofPattern(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()));
+    }
+    return ZonedDateTime.ofInstant(o.toInstant(), ZoneOffset.UTC).format(dateTimeFormatter);
+  }
+
+  @Override /* PojoSwap */
+  public Date unswap(BeanSession session, String s, ClassMeta<?> hint) {
+    DateTimeFormatter dateTimeFormatter = this.dateTimeFormatter;
+    if( StringUtils.isNotBlank(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()))) {
+      dateTimeFormatter = DateTimeFormatter.ofPattern(session.getProperty("format", String.class, RFC3339Utils.UTC_STANDARD_FMT.toString()));
+    }
+    return Date.from(LocalDateTime.parse(s, dateTimeFormatter).atZone(ZoneOffset.UTC).toInstant());
+  }
+
+}