Repository: zeppelin Updated Branches: refs/heads/master 878a8c76c -> 57e0dc883
[ZEPPELIN-1028] Fix exported notebook importing error ### What is this PR for? This bug seems to be produced by #862. Currently a exported notebook is not imported with below error message. ``` ERROR [2016-06-20 17:19:21,797] ({qtp559670971-14} NotebookServer.java[onMessage]:231) - Can't handle message com.google.gson.JsonSyntaxException: 2016-06-20T14:33:31-0700 at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:81) at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:66) at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:41) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172) at com.google.gson.Gson.fromJson(Gson.java:791) at org.apache.zeppelin.notebook.Notebook.importNote(Notebook.java:199) at org.apache.zeppelin.socket.NotebookServer.importNote(NotebookServer.java:656) at org.apache.zeppelin.socket.NotebookServer.onMessage(NotebookServer.java:175) at org.apache.zeppelin.socket.NotebookSocket.onWebSocketText(NotebookSocket.java:56) at org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver.onTextMessage(JettyListenerEventDriver.java:128) at org.eclipse.jetty.websocket.common.message.SimpleTextMessage.messageComplete(SimpleTextMessage.java:69) at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.appendMessage(AbstractEventDriver.java:65) at org.eclipse.jetty.websocket.common.events.JettyListenerEventDriver.onTextFrame(JettyListenerEventDriver.java:122) at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.incomingFrame(AbstractEventDriver.java:161) at org.eclipse.jetty.websocket.common.WebSocketSession.incomingFrame(WebSocketSession.java:309) at org.eclipse.jetty.websocket.common.extensions.ExtensionStack.incomingFrame(ExtensionStack.java:214) at org.eclipse.jetty.websocket.common.Parser.notifyFrame(Parser.java:220) at org.eclipse.jetty.websocket.common.Parser.parse(Parser.java:258) at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.readParse(AbstractWebSocketConnection.java:632) at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:480) at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Thread.java:745) Caused by: java.text.ParseException: Unparseable date: "2016-06-20T14:33:31-0700" at java.text.DateFormat.parse(DateFormat.java:366) at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:79) ``` ### What type of PR is it? Bug Fix ### Todos ### What is the Jira issue? [ZEPPELIN-1028](https://issues.apache.org/jira/browse/ZEPPELIN-1028) ### How should this be tested? 1. Apply this patch (Build the source and restart Zeppelin) 2. Export a notebook and try to import it again 3. It should be imported as before ### Screenshots (if appropriate) With this patch, we can import the below two types of date format notebooks. - Exported after #862 merged : `yyyy-MM-dd'T'HH:mm:ssZ` <img width="289" alt="screen shot 2016-06-22 at 12 18 01 pm" src="https://cloud.githubusercontent.com/assets/10060731/16280468/6ebad710-3874-11e6-9ce6-b38e239649a2.png"> - Exported before #862 merged : `MMM dd, yyyy HH:mm:ss` <img width="288" alt="screen shot 2016-06-22 at 12 17 31 pm" src="https://cloud.githubusercontent.com/assets/10060731/16280459/6a4f256e-3874-11e6-848e-ec1ff6e9b441.png"> ### Questions: * Does the licenses files need update? No * Is there breaking changes for older versions? No * Does this needs documentation? No Author: AhyoungRyu <fbdkdu...@hanmail.net> Closes #1055 from AhyoungRyu/ZEPPELIN-1028 and squashes the following commits: 8f91d2d [AhyoungRyu] Fix class description 829bcae [AhyoungRyu] Rename NotebookImportSerializer -> NotebookImportDeserializer 2dff9bb [AhyoungRyu] Support two date format for backward compatibility 2d8fc66 [AhyoungRyu] Remove new line 7c493bf [AhyoungRyu] Change date format in importNote 479c0d0 [AhyoungRyu] Fix exported notebook importing error Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/57e0dc88 Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/57e0dc88 Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/57e0dc88 Branch: refs/heads/master Commit: 57e0dc88310b9dbdece780beab5c9e3e496be1b9 Parents: 878a8c7 Author: AhyoungRyu <fbdkdu...@hanmail.net> Authored: Wed Jun 22 15:06:35 2016 -0700 Committer: Lee moon soo <m...@apache.org> Committed: Fri Jun 24 07:53:34 2016 -0700 ---------------------------------------------------------------------- .../apache/zeppelin/socket/NotebookServer.java | 3 +- .../org/apache/zeppelin/notebook/Notebook.java | 4 +- .../notebook/NotebookImportDeserializer.java | 53 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/57e0dc88/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java index 17650dd..f4cf9d9 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java @@ -77,8 +77,7 @@ public class NotebookServer extends WebSocketServlet implements } private static final Logger LOG = LoggerFactory.getLogger(NotebookServer.class); - Gson gson = new GsonBuilder() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create(); + Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create(); final Map<String, List<NotebookSocket>> noteSocketMap = new HashMap<>(); final Queue<NotebookSocket> connectedSockets = new ConcurrentLinkedQueue<>(); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/57e0dc88/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java index adaaa2a..d590223 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java @@ -195,7 +195,9 @@ public class Notebook { throws IOException { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.create(); + + Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer()) + .create(); JsonReader reader = new JsonReader(new StringReader(sourceJson)); reader.setLenient(true); Note newNote; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/57e0dc88/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java new file mode 100644 index 0000000..1aadf75 --- /dev/null +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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 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 org.apache.zeppelin.notebook; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +import java.lang.reflect.Type; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.Locale; + +/** + * importNote date format deserializer + */ +public class NotebookImportDeserializer implements JsonDeserializer<Date> { + private static final String[] DATE_FORMATS = new String[] { + "yyyy-MM-dd'T'HH:mm:ssZ", + "MMM dd, yyyy HH:mm:ss" + }; + + @Override + public Date deserialize(JsonElement jsonElement, Type typeOF, + JsonDeserializationContext context) throws JsonParseException { + for (String format : DATE_FORMATS) { + try { + return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString()); + } catch (ParseException e) { + } + } + throw new JsonParseException("Unparsable date: \"" + jsonElement.getAsString() + + "\". Supported formats: " + Arrays.toString(DATE_FORMATS)); + } +}