Repository: zeppelin Updated Branches: refs/heads/master f3f24f300 -> f36b1a157
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java index 9d32212..80d5356 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/HeliumConf.java @@ -16,12 +16,21 @@ */ package org.apache.zeppelin.helium; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.zeppelin.common.JsonSerializable; + import java.util.*; /** * Helium config. This object will be persisted to conf/helium.conf */ -public class HeliumConf { +public class HeliumConf implements JsonSerializable { + private static final Gson gson = new GsonBuilder() + .setPrettyPrinting() + .registerTypeAdapter(HeliumRegistry.class, new HeliumRegistrySerializer()) + .create(); + // enabled packages {name, version} private Map<String, String> enabled = Collections.synchronizedMap(new HashMap<String, String>()); @@ -91,4 +100,12 @@ public class HeliumConf { public void setBundleDisplayOrder(List<String> orderedPackageList) { bundleDisplayOrder = Collections.synchronizedList(orderedPackageList); } + + public String toJson() { + return gson.toJson(this); + } + + public static HeliumConf fromJson(String json) { + return gson.fromJson(json, HeliumConf.class); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java index 271f73f..c2234c6 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/NpmPackage.java @@ -16,13 +16,26 @@ */ package org.apache.zeppelin.helium; +import com.google.gson.Gson; +import org.apache.zeppelin.common.JsonSerializable; + import java.util.Map; /** * To read package.json */ -public class NpmPackage { +public class NpmPackage implements JsonSerializable { + private static final Gson gson = new Gson(); + public String name; public String version; public Map<String, String> dependencies; + + public String toJson() { + return gson.toJson(this); + } + + public static NpmPackage fromJson(String json) { + return gson.fromJson(json, NpmPackage.class); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java index 3414209..4175cad 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/helium/WebpackResult.java @@ -16,10 +16,23 @@ */ package org.apache.zeppelin.helium; +import com.google.gson.Gson; +import org.apache.zeppelin.common.JsonSerializable; + /** * Represetns webpack json format result */ -public class WebpackResult { +public class WebpackResult implements JsonSerializable { + private static final Gson gson = new Gson(); + public final String [] errors = new String[0]; public final String [] warnings = new String[0]; + + public String toJson() { + return gson.toJson(this); + } + + public static WebpackResult fromJson(String json) { + return gson.fromJson(json, WebpackResult.class); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java index 0df8f67..bbc2b3b 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java @@ -18,70 +18,35 @@ package org.apache.zeppelin.interpreter; import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import org.apache.commons.lang.NullArgumentException; +import org.apache.zeppelin.conf.ZeppelinConfiguration; +import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; +import org.apache.zeppelin.dep.DependencyResolver; +import org.apache.zeppelin.display.AngularObjectRegistry; +import org.apache.zeppelin.display.AngularObjectRegistryListener; +import org.apache.zeppelin.helium.ApplicationEventListener; +import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry; +import org.apache.zeppelin.interpreter.remote.RemoteInterpreter; +import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonatype.aether.RepositoryException; + import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Type; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.nio.charset.StandardCharsets; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.internal.StringMap; -import com.google.gson.reflect.TypeToken; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.NullArgumentException; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonatype.aether.RepositoryException; -import org.sonatype.aether.repository.Authentication; -import org.sonatype.aether.repository.Proxy; -import org.sonatype.aether.repository.RemoteRepository; - -import org.apache.zeppelin.conf.ZeppelinConfiguration; -import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; -import org.apache.zeppelin.dep.Dependency; -import org.apache.zeppelin.dep.DependencyResolver; -import org.apache.zeppelin.display.AngularObjectRegistry; -import org.apache.zeppelin.display.AngularObjectRegistryListener; -import org.apache.zeppelin.helium.ApplicationEventListener; -import org.apache.zeppelin.interpreter.Interpreter.RegisteredInterpreter; -import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry; -import org.apache.zeppelin.interpreter.remote.RemoteInterpreter; -import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener; -import org.apache.zeppelin.scheduler.Job; -import org.apache.zeppelin.scheduler.Job.Status; /** * Manage interpreters. @@ -95,9 +60,6 @@ public class InterpreterFactory implements InterpreterGroupFactory { private ZeppelinConfiguration conf; private final InterpreterSettingManager interpreterSettingManager; - - private Gson gson; - private AngularObjectRegistryListener angularObjectRegistryListener; private final RemoteInterpreterProcessListener remoteInterpreterProcessListener; private final ApplicationEventListener appEventListener; @@ -120,10 +82,6 @@ public class InterpreterFactory implements InterpreterGroupFactory { this.appEventListener = appEventListener; this.shiroEnabled = shiroEnabled; - GsonBuilder builder = new GsonBuilder(); - builder.setPrettyPrinting(); - gson = builder.create(); - this.interpreterSettingManager = interpreterSettingManager; //TODO(jl): Fix it not to use InterpreterGroupFactory interpreterSettingManager.setInterpreterGroupFactory(this); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java index 786a723..ca688dc 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java @@ -17,6 +17,9 @@ package org.apache.zeppelin.interpreter; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.zeppelin.common.JsonSerializable; import org.sonatype.aether.repository.RemoteRepository; import java.util.List; @@ -25,8 +28,19 @@ import java.util.Map; /** * */ -public class InterpreterInfoSaving { +public class InterpreterInfoSaving implements JsonSerializable { + + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + public Map<String, InterpreterSetting> interpreterSettings; public Map<String, List<String>> interpreterBindings; public List<RemoteRepository> interpreterRepositories; + + public String toJson() { + return gson.toJson(this); + } + + public static InterpreterInfoSaving fromJson(String json) { + return gson.fromJson(json, InterpreterInfoSaving.class); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java index 8270aba..1327e09 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java @@ -63,6 +63,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; @@ -162,11 +163,12 @@ public class InterpreterSettingManager { return; } InterpreterInfoSaving infoSaving; - try (BufferedReader json = + try (BufferedReader jsonReader = Files.newBufferedReader(interpreterBindingPath, StandardCharsets.UTF_8)) { JsonParser jsonParser = new JsonParser(); - JsonObject jsonObject = jsonParser.parse(json).getAsJsonObject(); + JsonObject jsonObject = jsonParser.parse(jsonReader).getAsJsonObject(); infoSaving = gson.fromJson(jsonObject.toString(), InterpreterInfoSaving.class); + for (String k : infoSaving.interpreterSettings.keySet()) { InterpreterSetting setting = infoSaving.interpreterSettings.get(k); List<InterpreterInfo> infos = setting.getInterpreterInfos(); @@ -236,7 +238,7 @@ public class InterpreterSettingManager { info.interpreterSettings = interpreterSettings; info.interpreterRepositories = interpreterRepositories; - jsonString = gson.toJson(info); + jsonString = info.toJson(); } if (!Files.exists(interpreterBindingPath)) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java index ed8982b..9cea693 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java @@ -515,8 +515,8 @@ public class RemoteInterpreter extends Interpreter { private RemoteInterpreterContext convert(InterpreterContext ic) { return new RemoteInterpreterContext(ic.getNoteId(), ic.getParagraphId(), ic.getReplName(), - ic.getParagraphTitle(), ic.getParagraphText(), gson.toJson(ic.getAuthenticationInfo()), - gson.toJson(ic.getConfig()), gson.toJson(ic.getGui()), gson.toJson(ic.getRunners())); + ic.getParagraphTitle(), ic.getParagraphText(), ic.getAuthenticationInfo().toJson(), + gson.toJson(ic.getConfig()), ic.getGui().toJson(), gson.toJson(ic.getRunners())); } private InterpreterResult convert(RemoteInterpreterResult result) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java index b3cb6c3..ff915a3 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java @@ -26,8 +26,12 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import com.google.common.annotations.VisibleForTesting; import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.common.JsonSerializable; import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.display.AngularObject; import org.apache.zeppelin.display.AngularObjectRegistry; @@ -35,6 +39,7 @@ import org.apache.zeppelin.display.Input; import org.apache.zeppelin.interpreter.*; import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; +import org.apache.zeppelin.notebook.json.NotebookTypeAdapterFactory; import org.apache.zeppelin.notebook.repo.NotebookRepo; import org.apache.zeppelin.notebook.utility.IdHashes; import org.apache.zeppelin.resource.ResourcePoolUtils; @@ -52,12 +57,26 @@ import com.google.gson.Gson; /** * Binded interpreters for a note */ -public class Note implements Serializable, ParagraphJobListener { +public class Note implements ParagraphJobListener, JsonSerializable { private static final Logger logger = LoggerFactory.getLogger(Note.class); private static final long serialVersionUID = 7920699076577612429L; - private static final Gson gson = new GsonBuilder() - .registerTypeAdapterFactory(Input.TypeAdapterFactory) - .create(); + private static Gson gson = new GsonBuilder() + .setPrettyPrinting() + .registerTypeAdapterFactory(new NotebookTypeAdapterFactory<Paragraph>(Paragraph.class) { + @Override + protected void beforeWrite(Paragraph source, JsonElement toSerialize) { + Map<String, ParagraphRuntimeInfo> runtimeInfos = source.getRuntimeInfos(); + if (runtimeInfos != null) { + JsonElement jsonTree = gson.toJsonTree(runtimeInfos); + if (toSerialize instanceof JsonObject) { + JsonObject jsonObj = (JsonObject) toSerialize; + jsonObj.add("runtimeInfos", jsonTree); + } + } + } + }).setDateFormat("yyyy-MM-dd HH:mm:ss.SSS") + .registerTypeAdapter(Date.class, new NotebookImportDeserializer()) + .registerTypeAdapterFactory(Input.TypeAdapterFactory).create(); // threadpool for delayed persist of note private static final ScheduledThreadPoolExecutor delayedPersistThreadPool = @@ -323,7 +342,7 @@ public class Note implements Serializable, ParagraphJobListener { try { Gson gson = new Gson(); String resultJson = gson.toJson(srcParagraph.getReturn()); - InterpreterResult result = gson.fromJson(resultJson, InterpreterResult.class); + InterpreterResult result = InterpreterResult.fromJson(resultJson); newParagraph.setReturn(result, null); } catch (Exception e) { // 'result' part of Note consists of exception, instead of actual interpreter results @@ -898,11 +917,6 @@ public class Note implements Serializable, ParagraphJobListener { } public static Note fromJson(String json) { - GsonBuilder gsonBuilder = - new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer()) - .create(); Note note = gson.fromJson(json, Note.class); convertOldInput(note); return note; @@ -913,4 +927,50 @@ public class Note implements Serializable, ParagraphJobListener { p.settings.convertOldInput(); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Note note = (Note) o; + + if (paragraphs != null ? !paragraphs.equals(note.paragraphs) : note.paragraphs != null) { + return false; + } + //TODO(zjffdu) exclude name because FolderView.index use Note as key and consider different name + //as same note + // if (name != null ? !name.equals(note.name) : note.name != null) return false; + if (id != null ? !id.equals(note.id) : note.id != null) { + return false; + } + if (angularObjects != null ? + !angularObjects.equals(note.angularObjects) : note.angularObjects != null) { + return false; + } + if (config != null ? !config.equals(note.config) : note.config != null) { + return false; + } + return info != null ? info.equals(note.info) : note.info == null; + + } + + @Override + public int hashCode() { + int result = paragraphs != null ? paragraphs.hashCode() : 0; + // result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + (id != null ? id.hashCode() : 0); + result = 31 * result + (angularObjects != null ? angularObjects.hashCode() : 0); + result = 31 * result + (config != null ? config.hashCode() : 0); + result = 31 * result + (info != null ? info.hashCode() : 0); + return result; + } + + @VisibleForTesting + public static Gson getGson() { + return gson; + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/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 720a3be..07febf1 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 @@ -182,14 +182,11 @@ public class Notebook implements NoteEventListener { * @throws IOException, IllegalArgumentException */ public String exportNote(String noteId) throws IOException, IllegalArgumentException { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.create(); Note note = getNote(noteId); if (note == null) { throw new IllegalArgumentException(noteId + " not found"); } - return gson.toJson(note); + return note.toJson(); } /** @@ -202,16 +199,9 @@ public class Notebook implements NoteEventListener { */ public Note importNote(String sourceJson, String noteName, AuthenticationInfo subject) throws IOException { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - - Gson gson = - gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer()).create(); - JsonReader reader = new JsonReader(new StringReader(sourceJson)); - reader.setLenient(true); Note newNote; try { - Note oldNote = gson.fromJson(reader, Note.class); + Note oldNote = Note.fromJson(sourceJson); convertFromSingleResultToMultipleResultsFormat(oldNote); newNote = createNote(subject); if (noteName != null) http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java index 8fcecf4..500f068 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorization.java @@ -110,8 +110,7 @@ public class NotebookAuthorization { fis.close(); String json = sb.toString(); - NotebookAuthorizationInfoSaving info = gson.fromJson(json, - NotebookAuthorizationInfoSaving.class); + NotebookAuthorizationInfoSaving info = NotebookAuthorizationInfoSaving.fromJson(json); authInfo = info.authInfo; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java index 38cd0b6..629e400 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookAuthorizationInfoSaving.java @@ -17,12 +17,26 @@ package org.apache.zeppelin.notebook; +import com.google.gson.Gson; +import org.apache.zeppelin.common.JsonSerializable; + import java.util.Map; import java.util.Set; /** * Only used for saving NotebookAuthorization info */ -public class NotebookAuthorizationInfoSaving { +public class NotebookAuthorizationInfoSaving implements JsonSerializable { + + private static final Gson gson = new Gson(); + public Map<String, Map<String, Set<String>>> authInfo; + + public String toJson() { + return gson.toJson(this); + } + + public static NotebookAuthorizationInfoSaving fromJson(String json) { + return gson.fromJson(json, NotebookAuthorizationInfoSaving.class); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/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 index 86e0f0b..0b8eed8 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/NotebookImportDeserializer.java @@ -36,7 +36,8 @@ public class NotebookImportDeserializer implements JsonDeserializer<Date> { private static final String[] DATE_FORMATS = new String[] { "yyyy-MM-dd'T'HH:mm:ssZ", "MMM d, yyyy h:mm:ss a", - "MMM dd, yyyy HH:mm:ss" + "MMM dd, yyyy HH:mm:ss", + "yyyy-MM-dd HH:mm:ss.SSS" }; @Override http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java index 9bb5d21..be88a1b 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java @@ -20,6 +20,7 @@ package org.apache.zeppelin.notebook; import com.google.common.collect.Maps; import com.google.common.base.Strings; import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.common.JsonSerializable; import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.display.AngularObject; import org.apache.zeppelin.display.AngularObjectRegistry; @@ -49,7 +50,7 @@ import com.google.common.annotations.VisibleForTesting; /** * Paragraph is a representation of an execution unit. */ -public class Paragraph extends Job implements Serializable, Cloneable { +public class Paragraph extends Job implements Cloneable, JsonSerializable { private static final long serialVersionUID = -6328572073497992016L; @@ -755,4 +756,72 @@ public class Paragraph extends Job implements Serializable, Cloneable { public Map<String, ParagraphRuntimeInfo> getRuntimeInfos() { return runtimeInfos; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + + Paragraph paragraph = (Paragraph) o; + + if (title != null ? !title.equals(paragraph.title) : paragraph.title != null) { + return false; + } + if (text != null ? !text.equals(paragraph.text) : paragraph.text != null) { + return false; + } + if (user != null ? !user.equals(paragraph.user) : paragraph.user != null) { + return false; + } + if (dateUpdated != null ? + !dateUpdated.equals(paragraph.dateUpdated) : paragraph.dateUpdated != null) { + return false; + } + if (config != null ? !config.equals(paragraph.config) : paragraph.config != null) { + return false; + } + if (settings != null ? !settings.equals(paragraph.settings) : paragraph.settings != null) { + return false; + } + if (results != null ? !results.equals(paragraph.results) : paragraph.results != null) { + return false; + } + if (result != null ? !result.equals(paragraph.result) : paragraph.result != null) { + return false; + } + return runtimeInfos != null ? + runtimeInfos.equals(paragraph.runtimeInfos) : paragraph.runtimeInfos == null; + + } + + @Override + public int hashCode() { + int result1 = super.hashCode(); + result1 = 31 * result1 + (title != null ? title.hashCode() : 0); + result1 = 31 * result1 + (text != null ? text.hashCode() : 0); + result1 = 31 * result1 + (user != null ? user.hashCode() : 0); + result1 = 31 * result1 + (dateUpdated != null ? dateUpdated.hashCode() : 0); + result1 = 31 * result1 + (config != null ? config.hashCode() : 0); + result1 = 31 * result1 + (settings != null ? settings.hashCode() : 0); + result1 = 31 * result1 + (results != null ? results.hashCode() : 0); + result1 = 31 * result1 + (result != null ? result.hashCode() : 0); + result1 = 31 * result1 + (runtimeInfos != null ? runtimeInfos.hashCode() : 0); + return result1; + } + + public String toJson() { + return Note.getGson().toJson(this); + } + + public static Paragraph fromJson(String json) { + return Note.getGson().fromJson(json, Paragraph.class); + } + } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java new file mode 100644 index 0000000..2ed7df0 --- /dev/null +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/json/NotebookTypeAdapterFactory.java @@ -0,0 +1,82 @@ +/* + * 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.json; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +/** + * Custom adapter type factory + * Modify the jsonObject before serailaization/deserialization + * @param <C> the type whose json is to be customized for serialization/deserialization + */ +public class NotebookTypeAdapterFactory<C> implements TypeAdapterFactory { + private final Class<C> customizedClass; + + public NotebookTypeAdapterFactory(Class<C> customizedClass) { + this.customizedClass = customizedClass; + } + + @SuppressWarnings("unchecked") + // we use a runtime check to guarantee that 'C' and 'T' are equal + public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { + return type.getRawType() == customizedClass ? (TypeAdapter<T>) customizeTypeAdapter(gson, + (TypeToken<C>) type) : null; + } + + private TypeAdapter<C> customizeTypeAdapter(Gson gson, TypeToken<C> type) { + final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type); + final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class); + return new TypeAdapter<C>() { + @Override + public void write(JsonWriter out, C value) throws IOException { + JsonElement tree = delegate.toJsonTree(value); + beforeWrite(value, tree); + elementAdapter.write(out, tree); + } + + @Override + public C read(JsonReader in) throws IOException { + JsonElement tree = elementAdapter.read(in); + afterRead(tree); + return delegate.fromJsonTree(tree); + } + }; + } + + /** + * Override this to change {@code toSerialize} before it is written to the + * outgoing JSON stream. + */ + protected void beforeWrite(C source, JsonElement toSerialize) { + } + + /** + * Override this to change {@code deserialized} before it parsed into the + * application type. + */ + protected void afterRead(JsonElement deserialized) { + } +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java index 5ef3c16..de337fa 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java @@ -25,7 +25,6 @@ import java.io.Writer; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.util.Collections; -import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -35,15 +34,12 @@ import org.apache.commons.lang.StringUtils; import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.NoteInfo; -import org.apache.zeppelin.notebook.NotebookImportDeserializer; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.scheduler.Job; import org.apache.zeppelin.user.AuthenticationInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.microsoft.azure.storage.CloudStorageAccount; import com.microsoft.azure.storage.StorageException; import com.microsoft.azure.storage.file.CloudFile; @@ -132,12 +128,6 @@ public class AzureNotebookRepo implements NotebookRepo { String json = IOUtils.toString(ins, conf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_ENCODING)); ins.close(); - - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer()) - .create(); - Note note = Note.fromJson(json); for (Paragraph p : note.getParagraphs()) { @@ -156,10 +146,7 @@ public class AzureNotebookRepo implements NotebookRepo { @Override public void save(Note note, AuthenticationInfo subject) throws IOException { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.create(); - String json = gson.toJson(note); + String json = note.toJson(); ByteArrayOutputStream output = new ByteArrayOutputStream(); Writer writer = new OutputStreamWriter(output); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java index 9502cf3..273d75d 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java @@ -1,7 +1,5 @@ package org.apache.zeppelin.notebook.repo; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.mongodb.MongoBulkWriteException; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; @@ -18,7 +16,6 @@ import com.mongodb.client.model.UpdateOptions; import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.NoteInfo; -import org.apache.zeppelin.notebook.NotebookImportDeserializer; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.notebook.ApplicationState; import org.apache.zeppelin.scheduler.Job; @@ -164,10 +161,7 @@ public class MongoNotebookRepo implements NotebookRepo { // document to JSON String json = doc.toJson(); // JSON to note - Gson gson = new GsonBuilder() - .registerTypeAdapter(Date.class, new NotebookImportDeserializer()) - .create(); - Note note = gson.fromJson(json, Note.class); + Note note = Note.fromJson(json); for (Paragraph p : note.getParagraphs()) { if (p.getStatus() == Job.Status.PENDING || p.getStatus() == Job.Status.RUNNING) { @@ -192,8 +186,7 @@ public class MongoNotebookRepo implements NotebookRepo { */ private Document noteToDocument(Note note) { // note to JSON - Gson gson = new GsonBuilder().create(); - String json = gson.toJson(note); + String json = note.toJson(); // JSON to document Document doc = Document.parse(json); // set object id as note id http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java index 71fa19f..16b270c 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java @@ -24,7 +24,6 @@ import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Collections; -import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -36,7 +35,6 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.NoteInfo; -import org.apache.zeppelin.notebook.NotebookImportDeserializer; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.user.AuthenticationInfo; @@ -61,8 +59,6 @@ import com.amazonaws.regions.Region; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectSummary; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; /** * Backend for storing Notebooks on S3 @@ -186,11 +182,6 @@ public class S3NotebookRepo implements NotebookRepo { } private Note getNote(String key) throws IOException { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.registerTypeAdapter(Date.class, new NotebookImportDeserializer()) - .create(); - S3Object s3object; try { s3object = s3client.getObject(new GetObjectRequest(bucketName, key)); @@ -226,10 +217,7 @@ public class S3NotebookRepo implements NotebookRepo { @Override public void save(Note note, AuthenticationInfo subject) throws IOException { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.create(); - String json = gson.toJson(note); + String json = note.toJson(); String key = user + "/" + "notebook" + "/" + note.getId() + "/" + "note.json"; File file = File.createTempFile("note", "json"); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java index c30f20f..4006d13 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java @@ -43,7 +43,6 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.notebook.ApplicationState; import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.NoteInfo; -import org.apache.zeppelin.notebook.NotebookImportDeserializer; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.user.AuthenticationInfo; @@ -51,8 +50,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; /** * @@ -164,8 +161,7 @@ public class VFSNotebookRepo implements NotebookRepo { if (!noteJson.exists()) { throw new IOException(noteJson.getName().toString() + " not found"); } - - + FileContent content = noteJson.getContent(); InputStream ins = content.getInputStream(); String json = IOUtils.toString(ins, conf.getString(ConfVars.ZEPPELIN_ENCODING)); @@ -222,10 +218,7 @@ public class VFSNotebookRepo implements NotebookRepo { @Override public synchronized void save(Note note, AuthenticationInfo subject) throws IOException { - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setPrettyPrinting(); - Gson gson = gsonBuilder.create(); - String json = gson.toJson(note); + String json = note.toJson(); FileObject rootDir = getRootDir(); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java index b072251..0257b8c 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinClient.java @@ -48,8 +48,6 @@ import org.eclipse.jetty.websocket.client.WebSocketClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; /** * Zeppelin websocket client. @@ -59,7 +57,6 @@ public class ZeppelinClient { private static final Logger LOG = LoggerFactory.getLogger(ZeppelinClient.class); private final URI zeppelinWebsocketUrl; private final WebSocketClient wsClient; - private static Gson gson; // Keep track of current open connection per notebook. private ConcurrentHashMap<String, Session> notesConnection; // Listen to every note actions. @@ -99,7 +96,6 @@ public class ZeppelinClient { private ZeppelinClient(String zeppelinUrl, String token, ZeppelinConfiguration conf) { zeppelinWebsocketUrl = URI.create(zeppelinUrl); wsClient = createNewWebsocketClient(); - gson = new Gson(); notesConnection = new ConcurrentHashMap<>(); schedulerService = SchedulerService.getInstance(); authModule = Authentication.initialize(token, conf); @@ -177,7 +173,7 @@ public class ZeppelinClient { zeppelinMsg.ticket = authModule.getTicket(); zeppelinMsg.roles = authModule.getRoles(); } - String msg = gson.toJson(zeppelinMsg); + String msg = zeppelinMsg.toJson(); return msg; } @@ -189,14 +185,12 @@ public class ZeppelinClient { if (StringUtils.isBlank(zeppelinMessage)) { return null; } - Message msg; try { - msg = gson.fromJson(zeppelinMessage, Message.class); - } catch (JsonSyntaxException ex) { - LOG.error("Cannot deserialize zeppelin message", ex); - msg = null; + return Message.fromJson(zeppelinMessage); + } catch (Exception e) { + LOG.error("Fail to parse zeppelinMessage", e); + return null; } - return msg; } private Session openWatcherSession() { @@ -316,7 +310,7 @@ public class ZeppelinClient { if (StringUtils.isEmpty(token)) { relayToAllZeppelinHub(hubMsg, noteId); } else { - client.relayToZeppelinHub(hubMsg.serialize(), token); + client.relayToZeppelinHub(hubMsg.toJson(), token); } } @@ -336,7 +330,7 @@ public class ZeppelinClient { if (noteAuth.isReader(noteId, userAndRoles)) { token = userTokens.get(user); hubMsg.meta.put("token", token); - client.relayToZeppelinHub(hubMsg.serialize(), token); + client.relayToZeppelinHub(hubMsg.toJson(), token); } } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java index 4eb00df..bc34324 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/ZeppelinhubClient.java @@ -195,7 +195,7 @@ public class ZeppelinhubClient { } public void handleMsgFromZeppelinHub(String message) { - ZeppelinhubMessage hubMsg = ZeppelinhubMessage.deserialize(message); + ZeppelinhubMessage hubMsg = ZeppelinhubMessage.fromJson(message); if (hubMsg.equals(ZeppelinhubMessage.EMPTY)) { LOG.error("Cannot handle ZeppelinHub message is empty"); return; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java index 95a1e77..43adf4a 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/listener/WatcherWebsocket.java @@ -27,15 +27,12 @@ import org.eclipse.jetty.websocket.api.WebSocketListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; - /** * Zeppelin Watcher that will forward user note to ZeppelinHub. * */ public class WatcherWebsocket implements WebSocketListener { private static final Logger LOG = LoggerFactory.getLogger(ZeppelinWebsocket.class); - private static final Gson GSON = new Gson(); private static final String watcherPrincipal = "watcher"; public Session connection; @@ -59,7 +56,7 @@ public class WatcherWebsocket implements WebSocketListener { Message watcherMsg = new Message(OP.WATCHER); watcherMsg.principal = watcherPrincipal; watcherMsg.ticket = TicketContainer.instance.getTicket(watcherPrincipal); - session.getRemote().sendStringByFuture(GSON.toJson(watcherMsg)); + session.getRemote().sendStringByFuture(watcherMsg.toJson()); } @Override @@ -69,7 +66,7 @@ public class WatcherWebsocket implements WebSocketListener { @Override public void onWebSocketText(String message) { - WatcherMessage watcherMsg = GSON.fromJson(message, WatcherMessage.class); + WatcherMessage watcherMsg = WatcherMessage.fromJson(message); if (StringUtils.isBlank(watcherMsg.noteId)) { return; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java index aa1ce21..4f7c652 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessage.java @@ -19,6 +19,7 @@ package org.apache.zeppelin.notebook.repo.zeppelinhub.websocket.protocol; import java.util.Map; import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.common.JsonSerializable; import org.apache.zeppelin.notebook.repo.zeppelinhub.websocket.Client; import org.apache.zeppelin.notebook.socket.Message; import org.apache.zeppelin.notebook.socket.Message.OP; @@ -33,7 +34,7 @@ import com.google.gson.JsonSyntaxException; * Zeppelinhub message class. * */ -public class ZeppelinhubMessage { +public class ZeppelinhubMessage implements JsonSerializable { private static final Gson gson = new Gson(); private static final Logger LOG = LoggerFactory.getLogger(Client.class); public static final ZeppelinhubMessage EMPTY = new ZeppelinhubMessage(); @@ -64,11 +65,11 @@ public class ZeppelinhubMessage { return new ZeppelinhubMessage(zeppelinMsg.op, zeppelinMsg.data, meta); } - public String serialize() { + public String toJson() { return gson.toJson(this, ZeppelinhubMessage.class); } - public static ZeppelinhubMessage deserialize(String zeppelinhubMessage) { + public static ZeppelinhubMessage fromJson(String zeppelinhubMessage) { if (StringUtils.isBlank(zeppelinhubMessage)) { return EMPTY; } @@ -76,7 +77,7 @@ public class ZeppelinhubMessage { try { msg = gson.fromJson(zeppelinhubMessage, ZeppelinhubMessage.class); } catch (JsonSyntaxException ex) { - LOG.error("Cannot deserialize zeppelinhub message", ex); + LOG.error("Cannot fromJson zeppelinhub message", ex); msg = EMPTY; } return msg; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java index b88fd72..50da343 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/utils/ZeppelinhubUtils.java @@ -37,37 +37,37 @@ public class ZeppelinhubUtils { public static String liveMessage(String token) { if (StringUtils.isBlank(token)) { LOG.error("Cannot create Live message: token is null or empty"); - return ZeppelinhubMessage.EMPTY.serialize(); + return ZeppelinhubMessage.EMPTY.toJson(); } HashMap<String, Object> data = new HashMap<>(); data.put("token", token); return ZeppelinhubMessage .newMessage(ZeppelinHubOp.LIVE, data, new HashMap<String, String>()) - .serialize(); + .toJson(); } public static String deadMessage(String token) { if (StringUtils.isBlank(token)) { LOG.error("Cannot create Dead message: token is null or empty"); - return ZeppelinhubMessage.EMPTY.serialize(); + return ZeppelinhubMessage.EMPTY.toJson(); } HashMap<String, Object> data = new HashMap<>(); data.put("token", token); return ZeppelinhubMessage .newMessage(ZeppelinHubOp.DEAD, data, new HashMap<String, String>()) - .serialize(); + .toJson(); } public static String pingMessage(String token) { if (StringUtils.isBlank(token)) { LOG.error("Cannot create Ping message: token is null or empty"); - return ZeppelinhubMessage.EMPTY.serialize(); + return ZeppelinhubMessage.EMPTY.toJson(); } HashMap<String, Object> data = new HashMap<>(); data.put("token", token); return ZeppelinhubMessage .newMessage(ZeppelinHubOp.PING, data, new HashMap<String, String>()) - .serialize(); + .toJson(); } public static ZeppelinHubOp toZeppelinHubOp(String text) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java index 3784f5e..06c83e1 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java @@ -17,13 +17,16 @@ package org.apache.zeppelin.notebook.socket; +import com.google.gson.Gson; +import org.apache.zeppelin.common.JsonSerializable; + import java.util.HashMap; import java.util.Map; /** * Zeppelin websocket massage template class. */ -public class Message { +public class Message implements JsonSerializable { /** * Representation of event type. */ @@ -179,6 +182,7 @@ public class Message { PARAS_INFO // [s-c] paragraph runtime infos } + private static final Gson gson = new Gson(); public static final Message EMPTY = new Message(null); public OP op; @@ -212,4 +216,12 @@ public class Message { sb.append('}'); return sb.toString(); } + + public String toJson() { + return gson.toJson(this); + } + + public static Message fromJson(String json) { + return gson.fromJson(json, Message.class); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java index 0fb28cc..c982ca7 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/WatcherMessage.java @@ -17,11 +17,12 @@ package org.apache.zeppelin.notebook.socket; import com.google.gson.Gson; +import org.apache.zeppelin.common.JsonSerializable; /** * Zeppelin websocket massage template class for watcher socket. */ -public class WatcherMessage { +public class WatcherMessage implements JsonSerializable { public String message; public String noteId; @@ -39,10 +40,14 @@ public class WatcherMessage { this.subject = builder.subject; } - public String serialize() { + public String toJson() { return gson.toJson(this); } - + + public static WatcherMessage fromJson(String json) { + return gson.fromJson(json, WatcherMessage.class); + } + /** * Simple builder. */ http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java index 3d0fe1a..2e3812c 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java @@ -19,19 +19,6 @@ package org.apache.zeppelin.interpreter; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.Properties; - -import com.google.common.collect.Maps; -import com.google.gson.Gson; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.NullArgumentException; import org.apache.zeppelin.conf.ZeppelinConfiguration; @@ -40,7 +27,6 @@ import org.apache.zeppelin.dep.Dependency; import org.apache.zeppelin.dep.DependencyResolver; import org.apache.zeppelin.interpreter.mock.MockInterpreter1; import org.apache.zeppelin.interpreter.mock.MockInterpreter2; -import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.interpreter.remote.RemoteInterpreter; import org.apache.zeppelin.notebook.JobListenerFactory; import org.apache.zeppelin.notebook.Note; @@ -50,21 +36,22 @@ import org.apache.zeppelin.notebook.repo.NotebookRepo; import org.apache.zeppelin.notebook.repo.VFSNotebookRepo; import org.apache.zeppelin.scheduler.SchedulerFactory; import org.apache.zeppelin.search.SearchService; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; import org.quartz.SchedulerException; import org.sonatype.aether.RepositoryException; -import static org.junit.Assert.*; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; -import org.mockito.Mock; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; public class InterpreterFactoryTest { @@ -341,8 +328,7 @@ public class InterpreterFactoryTest { byte[] encoded = Files.readAllBytes(Paths.get(confFilePath)); String json = new String(encoded, "UTF-8"); - Gson gson = new Gson(); - InterpreterInfoSaving infoSaving = gson.fromJson(json, InterpreterInfoSaving.class); + InterpreterInfoSaving infoSaving = InterpreterInfoSaving.fromJson(json); Map<String, InterpreterSetting> interpreterSettings = infoSaving.interpreterSettings; for (String key : interpreterSettings.keySet()) { InterpreterSetting setting = interpreterSettings.get(key); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java index 0eb37df..69c1f86 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteTest.java @@ -17,6 +17,10 @@ package org.apache.zeppelin.notebook; +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import org.apache.zeppelin.display.AngularObject; +import org.apache.zeppelin.display.ui.TextBox; import org.apache.zeppelin.interpreter.Interpreter; import org.apache.zeppelin.interpreter.InterpreterFactory; import org.apache.zeppelin.interpreter.InterpreterResult; @@ -32,6 +36,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import java.util.Date; + import static org.junit.Assert.*; import static org.mockito.Mockito.*; @@ -233,4 +239,28 @@ public class NoteTest { assertNotEquals(System.identityHashCode(baseParagraph), System.identityHashCode(user2Paragraph)); assertNotEquals(System.identityHashCode(user1Paragraph), System.identityHashCode(user2Paragraph)); } + + public void testNoteJson() { + Note note = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener); + note.setName("/test_note"); + note.getConfig().put("config_1", "value_1"); + note.getInfo().put("info_1", "value_1"); + String pText = "%spark sc.version"; + Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS); + p.dateUpdated = new Date(); + p.setText(pText); + p.setResult("1.6.2"); + p.settings.getForms().put("textbox_1", new TextBox("name", "default_name")); + p.settings.getParams().put("textbox_1", "my_name"); + note.getAngularObjects().put("ao_1", Lists.newArrayList(new AngularObject("name_1", "value_1", note.getId(), p.getId(), null))); + + // test Paragraph Json + Paragraph p2 = Paragraph.fromJson(p.toJson()); + assertEquals(p2.settings, p.settings); + assertEquals(p2, p); + + // test Note Json + Note note2 = Note.fromJson(note.toJson()); + assertEquals(note2, note); + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java index ed329b6..495e17b 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java @@ -195,7 +195,15 @@ public class NotebookTest implements JobListenerFactory{ assertEquals(notes.size(), 2); assertEquals(notes.get(1).getId(), copiedNote.getId()); assertEquals(notes.get(1).getName(), copiedNote.getName()); - assertEquals(notes.get(1).getParagraphs(), copiedNote.getParagraphs()); + // format has make some changes due to + // Notebook.convertFromSingleResultToMultipleResultsFormat + assertEquals(notes.get(1).getParagraphs().size(), copiedNote.getParagraphs().size()); + assertEquals(notes.get(1).getParagraphs().get(0).getText(), + copiedNote.getParagraphs().get(0).getText()); + assertEquals(notes.get(1).getParagraphs().get(0).settings, + copiedNote.getParagraphs().get(0).settings); + assertEquals(notes.get(1).getParagraphs().get(0).title, + copiedNote.getParagraphs().get(0).title); // delete the notebook for (String note : noteNames) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java index 4cce203..1f07f4f 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/websocket/protocol/ZeppelinhubMessageTest.java @@ -17,7 +17,7 @@ public class ZeppelinhubMessageTest { public void testThatCanSerializeZeppelinHubMessage() { Map<String,String> meta = Maps.newHashMap(); meta.put("key1", "val1"); - String zeppelinHubMsg = ZeppelinhubMessage.newMessage(OP.LIST_NOTES, "my data", meta).serialize(); + String zeppelinHubMsg = ZeppelinhubMessage.newMessage(OP.LIST_NOTES, "my data", meta).toJson(); assertEquals(msg, zeppelinHubMsg); } @@ -27,7 +27,7 @@ public class ZeppelinhubMessageTest { Map<String,String> meta = Maps.newHashMap(); meta.put("key1", "val1"); ZeppelinhubMessage expected = ZeppelinhubMessage.newMessage(OP.LIST_NOTES.toString(), "my data", meta); - ZeppelinhubMessage zeppelinHubMsg = ZeppelinhubMessage.deserialize(msg); + ZeppelinhubMessage zeppelinHubMsg = ZeppelinhubMessage.fromJson(msg); assertEquals(expected.op, zeppelinHubMsg.op); assertEquals(expected.data, zeppelinHubMsg.data); @@ -36,8 +36,8 @@ public class ZeppelinhubMessageTest { @Test public void testThatInvalidStringReturnEmptyZeppelinhubMessage() { - assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.deserialize("")); - assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.deserialize("dwfewewrewr")); + assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.fromJson("")); + assertEquals(ZeppelinhubMessage.EMPTY, ZeppelinhubMessage.fromJson("dwfewewrewr")); } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f36b1a15/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java index 363ccf6..46134e5 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java @@ -147,10 +147,10 @@ public class DistributedResourcePoolTest { intp2.interpret("put key2 value2", context); ret = intp1.interpret("getAll", context); - assertEquals(2, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size()); + assertEquals(2, ResourceSet.fromJson(ret.message().get(0).getData()).size()); ret = intp2.interpret("getAll", context); - assertEquals(2, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size()); + assertEquals(2, ResourceSet.fromJson(ret.message().get(0).getData()).size()); ret = intp1.interpret("get key1", context); assertEquals("value1", gson.fromJson(ret.message().get(0).getData(), String.class)); @@ -173,7 +173,7 @@ public class DistributedResourcePoolTest { ResourceSet remoteSet = new ResourceSet(); Gson gson = new Gson(); for (Resource s : set) { - RemoteResource remoteResource = gson.fromJson(gson.toJson(s), RemoteResource.class); + RemoteResource remoteResource = RemoteResource.fromJson(s.toJson()); remoteResource.setResourcePoolConnector(this); remoteSet.add(remoteResource); } @@ -278,14 +278,14 @@ public class DistributedResourcePoolTest { // make sure no resources are automatically created ret = intp1.interpret("getAll", context); - assertEquals(2, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size()); + assertEquals(2, ResourceSet.fromJson(ret.message().get(0).getData()).size()); // invoke method in local resource pool and save result ret = intp1.interpret("invoke key1 length ret1", context); assertEquals("3", ret.message().get(0).getData()); ret = intp1.interpret("getAll", context); - assertEquals(3, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size()); + assertEquals(3, ResourceSet.fromJson(ret.message().get(0).getData()).size()); ret = intp1.interpret("get ret1", context); assertEquals("3", gson.fromJson(ret.message().get(0).getData(), String.class)); @@ -295,7 +295,7 @@ public class DistributedResourcePoolTest { assertEquals("5", ret.message().get(0).getData()); ret = intp1.interpret("getAll", context); - assertEquals(4, gson.fromJson(ret.message().get(0).getData(), ResourceSet.class).size()); + assertEquals(4, ResourceSet.fromJson(ret.message().get(0).getData()).size()); ret = intp1.interpret("get ret2", context); assertEquals("5", gson.fromJson(ret.message().get(0).getData(), String.class));