http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java index d6619fc..cea7e65 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-27") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-10-22") public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteInterpreterContext, RemoteInterpreterContext._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterContext> { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterContext"); @@ -63,7 +63,8 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI private static final org.apache.thrift.protocol.TField AUTHENTICATION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("authenticationInfo", org.apache.thrift.protocol.TType.STRING, (short)6); private static final org.apache.thrift.protocol.TField CONFIG_FIELD_DESC = new org.apache.thrift.protocol.TField("config", org.apache.thrift.protocol.TType.STRING, (short)7); private static final org.apache.thrift.protocol.TField GUI_FIELD_DESC = new org.apache.thrift.protocol.TField("gui", org.apache.thrift.protocol.TType.STRING, (short)8); - private static final org.apache.thrift.protocol.TField RUNNERS_FIELD_DESC = new org.apache.thrift.protocol.TField("runners", org.apache.thrift.protocol.TType.STRING, (short)9); + private static final org.apache.thrift.protocol.TField NOTE_GUI_FIELD_DESC = new org.apache.thrift.protocol.TField("noteGui", org.apache.thrift.protocol.TType.STRING, (short)9); + private static final org.apache.thrift.protocol.TField RUNNERS_FIELD_DESC = new org.apache.thrift.protocol.TField("runners", org.apache.thrift.protocol.TType.STRING, (short)10); private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>(); static { @@ -79,6 +80,7 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI public String authenticationInfo; // required public String config; // required public String gui; // required + public String noteGui; // required public String runners; // required /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ @@ -91,7 +93,8 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI AUTHENTICATION_INFO((short)6, "authenticationInfo"), CONFIG((short)7, "config"), GUI((short)8, "gui"), - RUNNERS((short)9, "runners"); + NOTE_GUI((short)9, "noteGui"), + RUNNERS((short)10, "runners"); private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); @@ -122,7 +125,9 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI return CONFIG; case 8: // GUI return GUI; - case 9: // RUNNERS + case 9: // NOTE_GUI + return NOTE_GUI; + case 10: // RUNNERS return RUNNERS; default: return null; @@ -183,6 +188,8 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); tmpMap.put(_Fields.GUI, new org.apache.thrift.meta_data.FieldMetaData("gui", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.NOTE_GUI, new org.apache.thrift.meta_data.FieldMetaData("noteGui", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); tmpMap.put(_Fields.RUNNERS, new org.apache.thrift.meta_data.FieldMetaData("runners", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); metaDataMap = Collections.unmodifiableMap(tmpMap); @@ -201,6 +208,7 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI String authenticationInfo, String config, String gui, + String noteGui, String runners) { this(); @@ -212,6 +220,7 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI this.authenticationInfo = authenticationInfo; this.config = config; this.gui = gui; + this.noteGui = noteGui; this.runners = runners; } @@ -243,6 +252,9 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI if (other.isSetGui()) { this.gui = other.gui; } + if (other.isSetNoteGui()) { + this.noteGui = other.noteGui; + } if (other.isSetRunners()) { this.runners = other.runners; } @@ -262,6 +274,7 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI this.authenticationInfo = null; this.config = null; this.gui = null; + this.noteGui = null; this.runners = null; } @@ -457,6 +470,30 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI } } + public String getNoteGui() { + return this.noteGui; + } + + public RemoteInterpreterContext setNoteGui(String noteGui) { + this.noteGui = noteGui; + return this; + } + + public void unsetNoteGui() { + this.noteGui = null; + } + + /** Returns true if field noteGui is set (has been assigned a value) and false otherwise */ + public boolean isSetNoteGui() { + return this.noteGui != null; + } + + public void setNoteGuiIsSet(boolean value) { + if (!value) { + this.noteGui = null; + } + } + public String getRunners() { return this.runners; } @@ -547,6 +584,14 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI } break; + case NOTE_GUI: + if (value == null) { + unsetNoteGui(); + } else { + setNoteGui((String)value); + } + break; + case RUNNERS: if (value == null) { unsetRunners(); @@ -584,6 +629,9 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI case GUI: return getGui(); + case NOTE_GUI: + return getNoteGui(); + case RUNNERS: return getRunners(); @@ -614,6 +662,8 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI return isSetConfig(); case GUI: return isSetGui(); + case NOTE_GUI: + return isSetNoteGui(); case RUNNERS: return isSetRunners(); } @@ -705,6 +755,15 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI return false; } + boolean this_present_noteGui = true && this.isSetNoteGui(); + boolean that_present_noteGui = true && that.isSetNoteGui(); + if (this_present_noteGui || that_present_noteGui) { + if (!(this_present_noteGui && that_present_noteGui)) + return false; + if (!this.noteGui.equals(that.noteGui)) + return false; + } + boolean this_present_runners = true && this.isSetRunners(); boolean that_present_runners = true && that.isSetRunners(); if (this_present_runners || that_present_runners) { @@ -761,6 +820,11 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI if (present_gui) list.add(gui); + boolean present_noteGui = true && (isSetNoteGui()); + list.add(present_noteGui); + if (present_noteGui) + list.add(noteGui); + boolean present_runners = true && (isSetRunners()); list.add(present_runners); if (present_runners) @@ -857,6 +921,16 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI return lastComparison; } } + lastComparison = Boolean.valueOf(isSetNoteGui()).compareTo(other.isSetNoteGui()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetNoteGui()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.noteGui, other.noteGui); + if (lastComparison != 0) { + return lastComparison; + } + } lastComparison = Boolean.valueOf(isSetRunners()).compareTo(other.isSetRunners()); if (lastComparison != 0) { return lastComparison; @@ -951,6 +1025,14 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI } first = false; if (!first) sb.append(", "); + sb.append("noteGui:"); + if (this.noteGui == null) { + sb.append("null"); + } else { + sb.append(this.noteGui); + } + first = false; + if (!first) sb.append(", "); sb.append("runners:"); if (this.runners == null) { sb.append("null"); @@ -1065,7 +1147,15 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; - case 9: // RUNNERS + case 9: // NOTE_GUI + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.noteGui = iprot.readString(); + struct.setNoteGuiIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // RUNNERS if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { struct.runners = iprot.readString(); struct.setRunnersIsSet(true); @@ -1128,6 +1218,11 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI oprot.writeString(struct.gui); oprot.writeFieldEnd(); } + if (struct.noteGui != null) { + oprot.writeFieldBegin(NOTE_GUI_FIELD_DESC); + oprot.writeString(struct.noteGui); + oprot.writeFieldEnd(); + } if (struct.runners != null) { oprot.writeFieldBegin(RUNNERS_FIELD_DESC); oprot.writeString(struct.runners); @@ -1175,10 +1270,13 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI if (struct.isSetGui()) { optionals.set(7); } - if (struct.isSetRunners()) { + if (struct.isSetNoteGui()) { optionals.set(8); } - oprot.writeBitSet(optionals, 9); + if (struct.isSetRunners()) { + optionals.set(9); + } + oprot.writeBitSet(optionals, 10); if (struct.isSetNoteId()) { oprot.writeString(struct.noteId); } @@ -1203,6 +1301,9 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI if (struct.isSetGui()) { oprot.writeString(struct.gui); } + if (struct.isSetNoteGui()) { + oprot.writeString(struct.noteGui); + } if (struct.isSetRunners()) { oprot.writeString(struct.runners); } @@ -1211,7 +1312,7 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI @Override public void read(org.apache.thrift.protocol.TProtocol prot, RemoteInterpreterContext struct) throws org.apache.thrift.TException { TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(9); + BitSet incoming = iprot.readBitSet(10); if (incoming.get(0)) { struct.noteId = iprot.readString(); struct.setNoteIdIsSet(true); @@ -1245,6 +1346,10 @@ public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteI struct.setGuiIsSet(true); } if (incoming.get(8)) { + struct.noteGui = iprot.readString(); + struct.setNoteGuiIsSet(true); + } + if (incoming.get(9)) { struct.runners = iprot.readString(); struct.setRunnersIsSet(true); }
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java index e252775..c75a42f 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-27") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-10-22") public class RemoteInterpreterEvent implements org.apache.thrift.TBase<RemoteInterpreterEvent, RemoteInterpreterEvent._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterEvent> { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterEvent"); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java index b18bad5..efe05aa 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-27") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-10-22") public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteInterpreterResult, RemoteInterpreterResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResult> { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResult"); @@ -59,6 +59,7 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.LIST, (short)2); private static final org.apache.thrift.protocol.TField CONFIG_FIELD_DESC = new org.apache.thrift.protocol.TField("config", org.apache.thrift.protocol.TType.STRING, (short)3); private static final org.apache.thrift.protocol.TField GUI_FIELD_DESC = new org.apache.thrift.protocol.TField("gui", org.apache.thrift.protocol.TType.STRING, (short)4); + private static final org.apache.thrift.protocol.TField NOTE_GUI_FIELD_DESC = new org.apache.thrift.protocol.TField("noteGui", org.apache.thrift.protocol.TType.STRING, (short)5); private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>(); static { @@ -70,13 +71,15 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn public List<RemoteInterpreterResultMessage> msg; // required public String config; // required public String gui; // required + public String noteGui; // required /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ public enum _Fields implements org.apache.thrift.TFieldIdEnum { CODE((short)1, "code"), MSG((short)2, "msg"), CONFIG((short)3, "config"), - GUI((short)4, "gui"); + GUI((short)4, "gui"), + NOTE_GUI((short)5, "noteGui"); private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); @@ -99,6 +102,8 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn return CONFIG; case 4: // GUI return GUI; + case 5: // NOTE_GUI + return NOTE_GUI; default: return null; } @@ -151,6 +156,8 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); tmpMap.put(_Fields.GUI, new org.apache.thrift.meta_data.FieldMetaData("gui", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.NOTE_GUI, new org.apache.thrift.meta_data.FieldMetaData("noteGui", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); metaDataMap = Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RemoteInterpreterResult.class, metaDataMap); } @@ -162,13 +169,15 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn String code, List<RemoteInterpreterResultMessage> msg, String config, - String gui) + String gui, + String noteGui) { this(); this.code = code; this.msg = msg; this.config = config; this.gui = gui; + this.noteGui = noteGui; } /** @@ -191,6 +200,9 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn if (other.isSetGui()) { this.gui = other.gui; } + if (other.isSetNoteGui()) { + this.noteGui = other.noteGui; + } } public RemoteInterpreterResult deepCopy() { @@ -203,6 +215,7 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn this.msg = null; this.config = null; this.gui = null; + this.noteGui = null; } public String getCode() { @@ -316,6 +329,30 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn } } + public String getNoteGui() { + return this.noteGui; + } + + public RemoteInterpreterResult setNoteGui(String noteGui) { + this.noteGui = noteGui; + return this; + } + + public void unsetNoteGui() { + this.noteGui = null; + } + + /** Returns true if field noteGui is set (has been assigned a value) and false otherwise */ + public boolean isSetNoteGui() { + return this.noteGui != null; + } + + public void setNoteGuiIsSet(boolean value) { + if (!value) { + this.noteGui = null; + } + } + public void setFieldValue(_Fields field, Object value) { switch (field) { case CODE: @@ -350,6 +387,14 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn } break; + case NOTE_GUI: + if (value == null) { + unsetNoteGui(); + } else { + setNoteGui((String)value); + } + break; + } } @@ -367,6 +412,9 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn case GUI: return getGui(); + case NOTE_GUI: + return getNoteGui(); + } throw new IllegalStateException(); } @@ -386,6 +434,8 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn return isSetConfig(); case GUI: return isSetGui(); + case NOTE_GUI: + return isSetNoteGui(); } throw new IllegalStateException(); } @@ -439,6 +489,15 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn return false; } + boolean this_present_noteGui = true && this.isSetNoteGui(); + boolean that_present_noteGui = true && that.isSetNoteGui(); + if (this_present_noteGui || that_present_noteGui) { + if (!(this_present_noteGui && that_present_noteGui)) + return false; + if (!this.noteGui.equals(that.noteGui)) + return false; + } + return true; } @@ -466,6 +525,11 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn if (present_gui) list.add(gui); + boolean present_noteGui = true && (isSetNoteGui()); + list.add(present_noteGui); + if (present_noteGui) + list.add(noteGui); + return list.hashCode(); } @@ -517,6 +581,16 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn return lastComparison; } } + lastComparison = Boolean.valueOf(isSetNoteGui()).compareTo(other.isSetNoteGui()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetNoteGui()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.noteGui, other.noteGui); + if (lastComparison != 0) { + return lastComparison; + } + } return 0; } @@ -568,6 +642,14 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn sb.append(this.gui); } first = false; + if (!first) sb.append(", "); + sb.append("noteGui:"); + if (this.noteGui == null) { + sb.append("null"); + } else { + sb.append(this.noteGui); + } + first = false; sb.append(")"); return sb.toString(); } @@ -654,6 +736,14 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; + case 5: // NOTE_GUI + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.noteGui = iprot.readString(); + struct.setNoteGuiIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; default: org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } @@ -696,6 +786,11 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn oprot.writeString(struct.gui); oprot.writeFieldEnd(); } + if (struct.noteGui != null) { + oprot.writeFieldBegin(NOTE_GUI_FIELD_DESC); + oprot.writeString(struct.noteGui); + oprot.writeFieldEnd(); + } oprot.writeFieldStop(); oprot.writeStructEnd(); } @@ -726,7 +821,10 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn if (struct.isSetGui()) { optionals.set(3); } - oprot.writeBitSet(optionals, 4); + if (struct.isSetNoteGui()) { + optionals.set(4); + } + oprot.writeBitSet(optionals, 5); if (struct.isSetCode()) { oprot.writeString(struct.code); } @@ -745,12 +843,15 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn if (struct.isSetGui()) { oprot.writeString(struct.gui); } + if (struct.isSetNoteGui()) { + oprot.writeString(struct.noteGui); + } } @Override public void read(org.apache.thrift.protocol.TProtocol prot, RemoteInterpreterResult struct) throws org.apache.thrift.TException { TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(4); + BitSet incoming = iprot.readBitSet(5); if (incoming.get(0)) { struct.code = iprot.readString(); struct.setCodeIsSet(true); @@ -777,6 +878,10 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn struct.gui = iprot.readString(); struct.setGuiIsSet(true); } + if (incoming.get(4)) { + struct.noteGui = iprot.readString(); + struct.setNoteGuiIsSet(true); + } } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java index a2aff29..37b3a87 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-27") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-10-22") public class RemoteInterpreterResultMessage implements org.apache.thrift.TBase<RemoteInterpreterResultMessage, RemoteInterpreterResultMessage._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResultMessage> { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResultMessage"); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java index def96fa..ba13f64 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterService.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-27") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-10-22") public class RemoteInterpreterService { public interface Iface { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ZeppelinServerResourceParagraphRunner.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ZeppelinServerResourceParagraphRunner.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ZeppelinServerResourceParagraphRunner.java index 78cb090..17b6bd8 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ZeppelinServerResourceParagraphRunner.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/ZeppelinServerResourceParagraphRunner.java @@ -51,7 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-27") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-10-22") public class ZeppelinServerResourceParagraphRunner implements org.apache.thrift.TBase<ZeppelinServerResourceParagraphRunner, ZeppelinServerResourceParagraphRunner._Fields>, java.io.Serializable, Cloneable, Comparable<ZeppelinServerResourceParagraphRunner> { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ZeppelinServerResourceParagraphRunner"); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/main/thrift/RemoteInterpreterService.thrift ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/main/thrift/RemoteInterpreterService.thrift b/zeppelin-interpreter/src/main/thrift/RemoteInterpreterService.thrift index f20fb90..559648a 100644 --- a/zeppelin-interpreter/src/main/thrift/RemoteInterpreterService.thrift +++ b/zeppelin-interpreter/src/main/thrift/RemoteInterpreterService.thrift @@ -27,7 +27,8 @@ struct RemoteInterpreterContext { 6: string authenticationInfo, 7: string config, // json serialized config 8: string gui, // json serialized gui - 9: string runners // json serialized runner + 9: string noteGui, // json serialized note gui + 10: string runners // json serialized runner } struct RemoteInterpreterResultMessage { @@ -39,6 +40,7 @@ struct RemoteInterpreterResult { 2: list<RemoteInterpreterResultMessage> msg, 3: string config, // json serialized config 4: string gui // json serialized gui + 5: string noteGui // json serialized note gui } enum RemoteInterpreterEventType { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/InputTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/InputTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/InputTest.java index d15fab4..d3d5a00 100644 --- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/InputTest.java +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/display/InputTest.java @@ -47,7 +47,7 @@ public class InputTest { public void testFormExtraction() { // textbox form String script = "${input_form=}"; - Map<String, Input> forms = Input.extractSimpleQueryForm(script); + Map<String, Input> forms = Input.extractSimpleQueryForm(script, false); assertEquals(1, forms.size()); Input form = forms.get("input_form"); assertEquals("input_form", form.name); @@ -57,14 +57,14 @@ public class InputTest { // textbox form with display name & default value script = "${input_form(Input Form)=xxx}"; - forms = Input.extractSimpleQueryForm(script); + forms = Input.extractSimpleQueryForm(script, false); form = forms.get("input_form"); assertEquals("xxx", form.defaultValue); assertTrue(form instanceof TextBox); // selection form script = "${select_form(Selection Form)=op1,op1|op2(Option 2)|op3}"; - form = Input.extractSimpleQueryForm(script).get("select_form"); + form = Input.extractSimpleQueryForm(script, false).get("select_form"); assertEquals("select_form", form.name); assertEquals("op1", form.defaultValue); assertTrue(form instanceof Select); @@ -74,7 +74,7 @@ public class InputTest { // checkbox form script = "${checkbox:checkbox_form=op1,op1|op2|op3}"; - form = Input.extractSimpleQueryForm(script).get("checkbox_form"); + form = Input.extractSimpleQueryForm(script, false).get("checkbox_form"); assertEquals("checkbox_form", form.name); assertTrue(form instanceof CheckBox); @@ -85,7 +85,7 @@ public class InputTest { // checkbox form with multiple default checks script = "${checkbox:checkbox_form(Checkbox Form)=op1|op3,op1(Option 1)|op2|op3}"; - form = Input.extractSimpleQueryForm(script).get("checkbox_form"); + form = Input.extractSimpleQueryForm(script, false).get("checkbox_form"); assertEquals("checkbox_form", form.name); assertEquals("Checkbox Form", form.displayName); assertTrue(form instanceof CheckBox); @@ -96,7 +96,7 @@ public class InputTest { // checkbox form with no default check script = "${checkbox:checkbox_form(Checkbox Form)=,op1(Option 1)|op2(Option 2)|op3(Option 3)}"; - form = Input.extractSimpleQueryForm(script).get("checkbox_form"); + form = Input.extractSimpleQueryForm(script, false).get("checkbox_form"); assertEquals("checkbox_form", form.name); assertEquals("Checkbox Form", form.displayName); assertTrue(form instanceof CheckBox); @@ -116,14 +116,14 @@ public class InputTest { params.put("input_form", "some_input"); params.put("select_form", "s_op2"); params.put("checkbox_form", new String[]{"c_op1", "c_op3"}); - String replaced = Input.getSimpleQuery(params, script); + String replaced = Input.getSimpleQuery(params, script, false); assertEquals("INPUT=some_inputSELECTED=s_op2\nCHECKED=c_op1,c_op3", replaced); // test form substitution with new forms script = "INPUT=${input_form=}SELECTED=${select_form(Selection Form)=,s_op1|s_op2|s_op3}\n" + "CHECKED=${checkbox:checkbox_form=c_op1|c_op2,c_op1|c_op2|c_op3}\n" + "NEW_CHECKED=${checkbox( and ):new_check=nc_a|nc_c,nc_a|nc_b|nc_c}"; - replaced = Input.getSimpleQuery(params, script); + replaced = Input.getSimpleQuery(params, script, false); assertEquals("INPUT=some_inputSELECTED=s_op2\nCHECKED=c_op1,c_op3\n" + "NEW_CHECKED=nc_a and nc_c", replaced); @@ -131,7 +131,7 @@ public class InputTest { script = "INPUT=${input_form=}SELECTED=${select_form(Selection Form)=,s_op1|s_op2|s_op3}\n" + "CHECKED=${checkbox:checkbox_form=c_op1|c_op2,c_op1|c_op2|c_op3_new}\n" + "NEW_CHECKED=${checkbox( and ):new_check=nc_a|nc_c,nc_a|nc_b|nc_c}"; - replaced = Input.getSimpleQuery(params, script); + replaced = Input.getSimpleQuery(params, script, false); assertEquals("INPUT=some_inputSELECTED=s_op2\nCHECKED=c_op1\n" + "NEW_CHECKED=nc_a and nc_c", replaced); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterContextTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterContextTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterContextTest.java index ecdf108..70e2cba 100644 --- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterContextTest.java +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterContextTest.java @@ -27,7 +27,7 @@ public class InterpreterContextTest { public void testThreadLocal() { assertNull(InterpreterContext.get()); - InterpreterContext.set(new InterpreterContext(null, null, null, null, null, null, null, null, null, null, null, null)); + InterpreterContext.set(new InterpreterContext(null, null, null, null, null, null, null, null, null, null, null, null, null)); assertNotNull(InterpreterContext.get()); InterpreterContext.remove(); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java index d341b58..4156691 100644 --- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java @@ -70,6 +70,7 @@ public class InterpreterTest { null, null, null, + null, null)); Properties p = new Properties(); p.put("p1", "replName #{noteId}, #{paragraphTitle}, #{paragraphId}, #{paragraphText}, #{replName}, #{noteId}, #{user}," + http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java index 8e325f2..165625e 100644 --- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java @@ -36,7 +36,7 @@ public class LazyOpenInterpreterTest { assertFalse("Interpreter is not open", lazyOpenInterpreter.isOpen()); InterpreterContext interpreterContext = - new InterpreterContext("note", "id", null, "title", "text", null, null, null, null, null, null, null); + new InterpreterContext("note", "id", null, "title", "text", null, null, null, null, null, null, null, null); lazyOpenInterpreter.interpret("intp 1", interpreterContext); assertTrue("Interpeter is open", lazyOpenInterpreter.isOpen()); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/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 a3e8714..184735a 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 @@ -33,10 +33,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.vfs2.FileSystemException; import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; -import org.apache.zeppelin.display.AngularObject; -import org.apache.zeppelin.display.AngularObjectRegistry; -import org.apache.zeppelin.display.AngularObjectRegistryListener; -import org.apache.zeppelin.display.Input; +import org.apache.zeppelin.display.*; import org.apache.zeppelin.helium.ApplicationEventListener; import org.apache.zeppelin.helium.HeliumPackage; import org.apache.zeppelin.interpreter.*; @@ -356,6 +353,12 @@ public class NotebookServer extends WebSocketServlet case WATCHER: switchConnectionToWatcher(conn, messagereceived); break; + case SAVE_NOTE_FORMS: + saveNoteForms(conn, userAndRoles, notebook, messagereceived); + break; + case REMOVE_NOTE_FORMS: + removeNoteForms(conn, userAndRoles, notebook, messagereceived); + break; default: break; } @@ -649,6 +652,8 @@ public class NotebookServer extends WebSocketServlet } public void broadcastParagraph(Note note, Paragraph p) { + broadcastNoteForms(note); + if (note.isPersonalizedMode()) { broadcastParagraphs(p.getUserParagraphMap(), p); } else { @@ -1227,7 +1232,6 @@ public class NotebookServer extends WebSocketServlet p.setText((String) fromMessage.get("paragraph")); } - note.persist(subject); if (note.isPersonalizedMode()) { @@ -2530,4 +2534,53 @@ public class NotebookServer extends WebSocketServlet } setting.clearNoteIdAndParaMap(); } + + public void broadcastNoteForms(Note note) { + GUI formsSettings = new GUI(); + formsSettings.setForms(note.getNoteForms()); + formsSettings.setParams(note.getNoteParams()); + + broadcast(note.getId(), new Message(OP.SAVE_NOTE_FORMS).put("formsData", formsSettings)); + } + + private void saveNoteForms(NotebookSocket conn, HashSet<String> userAndRoles, Notebook notebook, + Message fromMessage) throws IOException { + String noteId = (String) fromMessage.get("noteId"); + Map<String, Object> noteParams = (Map<String, Object>) fromMessage.get("noteParams"); + + if (!hasParagraphWriterPermission(conn, notebook, noteId, + userAndRoles, fromMessage.principal, "update")) { + return; + } + + Note note = notebook.getNote(noteId); + if (note != null) { + note.setNoteParams(noteParams); + + AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal); + note.persist(subject); + broadcastNoteForms(note); + } + } + + private void removeNoteForms(NotebookSocket conn, HashSet<String> userAndRoles, Notebook notebook, + Message fromMessage) throws IOException { + String noteId = (String) fromMessage.get("noteId"); + String formName = (String) fromMessage.get("formName"); + + if (!hasParagraphWriterPermission(conn, notebook, noteId, + userAndRoles, fromMessage.principal, "update")) { + return; + } + + Note note = notebook.getNote(noteId); + if (note != null) { + note.getNoteForms().remove(formName); + note.getNoteParams().remove(formName); + + AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal); + note.persist(subject); + broadcastNoteForms(note); + } + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java index 6f537fd..d2b38ea 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java @@ -63,6 +63,10 @@ abstract public class AbstractZeppelinIT { return "(//div[@ng-controller=\"ParagraphCtrl\"])[" + paragraphNo + "]"; } + protected String getNoteFormsXPath() { + return "(//div[@id='noteForms'])"; + } + protected boolean waitForParagraph(final int paragraphNo, final String state) { By locator = By.xpath(getParagraphXPath(paragraphNo) + "//div[contains(@class, 'control')]//span[2][contains(.,'" + state + "')]"); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java index 0911bf7..6c7dfa6 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java @@ -725,4 +725,164 @@ public class ParagraphActionsIT extends AbstractZeppelinIT { handleException("Exception in ParagraphActionsIT while testMultipleDynamicFormsSameType ", e); } } + + @Test + public void testNoteDynamicFormTextInput() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + createNewNote(); + + setTextOfParagraph(1, "%spark println(\"Hello \"+z.noteTextbox(\"name\", \"world\")) "); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + collector.checkThat("Output text is equal to value specified initially", driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), CoreMatchers.equalTo("Hello world")); + driver.findElement(By.xpath(getNoteFormsXPath() + "//input")).clear(); + driver.findElement(By.xpath(getNoteFormsXPath() + "//input")).sendKeys("Zeppelin"); + driver.findElement(By.xpath(getNoteFormsXPath() + "//input")).sendKeys(Keys.RETURN); + + collector.checkThat("After new data in text input form, output should not be changed", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Hello world")); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + collector.checkThat("Only after running the paragraph, we can see the newly updated output", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Hello Zeppelin")); + + setTextOfParagraph(2, "%spark println(\"Hello \"+z.noteTextbox(\"name\", \"world\")) "); + runParagraph(2); + waitForParagraph(2, "FINISHED"); + collector.checkThat("Running the another paragraph with same form, we can see value from note form", + driver.findElement(By.xpath(getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Hello Zeppelin")); + + deleteTestNotebook(driver); + + } catch (Exception e) { + handleException("Exception in ParagraphActionsIT while testNoteDynamicFormTextInput ", e); + } + } + + @Test + public void testNoteDynamicFormSelect() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + createNewNote(); + + setTextOfParagraph(1, "%spark println(\"Howdy \"+z.noteSelect(\"names\", Seq((\"1\",\"Alice\"), " + + "(\"2\",\"Bob\"),(\"3\",\"stranger\"))))"); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + collector.checkThat("Output text should not display any of the options in select form", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Howdy ")); + + Select dropDownMenu = new Select(driver.findElement(By.xpath("(" + (getNoteFormsXPath() + "//select)[1]")))); + + dropDownMenu.selectByVisibleText("Bob"); + collector.checkThat("After selection in drop down menu, output should not be changed", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Howdy ")); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + + collector.checkThat("After run paragraph again, we can see the newly updated output", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Howdy 2")); + + setTextOfParagraph(2, "%spark println(\"Howdy \"+z.noteSelect(\"names\", Seq((\"1\",\"Alice\"), " + + "(\"2\",\"Bob\"),(\"3\",\"stranger\"))))"); + + runParagraph(2); + waitForParagraph(2, "FINISHED"); + + collector.checkThat("Running the another paragraph with same form, we can see value from note form", + driver.findElement(By.xpath(getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("Howdy 2")); + + deleteTestNotebook(driver); + + } catch (Exception e) { + handleException("Exception in ParagraphActionsIT while testNoteDynamicFormSelect ", e); + } + } + + @Test + public void testDynamicNoteFormCheckbox() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + createNewNote(); + + setTextOfParagraph(1, "%spark val options = Seq((\"han\",\"Han\"), (\"leia\",\"Leia\"), " + + "(\"luke\",\"Luke\")); println(\"Greetings \"+z.noteCheckbox(\"skywalkers\",options).mkString(\" and \"))"); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + collector.checkThat("Output text should display all of the options included in check boxes", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.containsString("Greetings han and leia and luke")); + + WebElement firstCheckbox = driver.findElement(By.xpath("(" + getNoteFormsXPath() + "//input[@type='checkbox'])[1]")); + firstCheckbox.click(); + collector.checkThat("After unchecking one of the boxes, output should not be changed", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.containsString("Greetings han and leia and luke")); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + + collector.checkThat("After run paragraph again, we can see the newly updated output", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.containsString("Greetings leia and luke")); + + setTextOfParagraph(2, "%spark val options = Seq((\"han\",\"Han\"), (\"leia\",\"Leia\"), " + + "(\"luke\",\"Luke\")); println(\"Greetings \"+z.noteCheckbox(\"skywalkers\",options).mkString(\" and \"))"); + + runParagraph(2); + waitForParagraph(2, "FINISHED"); + + collector.checkThat("Running the another paragraph with same form, we can see value from note form", + driver.findElement(By.xpath(getParagraphXPath(2) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.containsString("Greetings leia and luke")); + + deleteTestNotebook(driver); + + } catch (Exception e) { + handleException("Exception in ParagraphActionsIT while testDynamicNoteFormCheckbox ", e); + } + } + + @Test + public void testWithNoteAndParagraphDynamicFormTextInput() throws Exception { + if (!endToEndTestEnabled()) { + return; + } + try { + createNewNote(); + + setTextOfParagraph(1, "%spark println(z.noteTextbox(\"name\", \"note\") + \" \" + z.textbox(\"name\", \"paragraph\")) "); + + runParagraph(1); + waitForParagraph(1, "FINISHED"); + + collector.checkThat("After run paragraph, we can see computed output from two forms", + driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(), + CoreMatchers.equalTo("note paragraph")); + + deleteTestNotebook(driver); + + } catch (Exception e) { + handleException("Exception in ParagraphActionsIT while testWithNoteAndParagraphDynamicFormTextInput ", e); + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.css ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.css b/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.css new file mode 100644 index 0000000..d15b240 --- /dev/null +++ b/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.css @@ -0,0 +1,24 @@ +import './note-create.css' + +.dynamicForm { + margin-right: 20px; + margin-left: 20px; +} + +.dynamicForm.form-horizontal .form-group { + margin-right: 0; + margin-left: 0; +} + +.dynamicForm.form-horizontal .form-group label { + padding-left: 0; +} + +.dynamicForm.form-horizontal .form-group .checkbox-item { + padding-left: 0; + padding-right: 10px; +} + +.dynamicForm.form-horizontal .form-group .checkbox-item input { + margin-right: 2px; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.html b/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.html new file mode 100644 index 0000000..4f3e715 --- /dev/null +++ b/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.html @@ -0,0 +1,86 @@ +<!-- +Licensed 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. +--> +<form id="{{id}}_form" role="form" + ng-show="!hide" + class="dynamicForm form-horizontal row"> + <div class="form-group col-sm-6 col-md-6 col-lg-4" + ng-repeat="formulaire in forms | toArray" + ng-init="loadForm(formulaire, params)"> + <label class="control-label input-sm" ng-class="{'disable': disable}">{{formulaire.name}}</label> + <a ng-if="removeaction"> + <i class="fa fa-times" + ng-click="removeaction(formulaire.name)" + tooltip-placement="bottom" uib-tooltip="Remove"> + </i> + </a> + <div ng-if="actiononchange === true"> + <input class="form-control input-sm" + ng-if="forms[formulaire.name].type == 'TextBox'" + ng-change="action()" + ng-model-options='{ debounce: 1000 }' + ng-model="params[formulaire.name]" + ng-class="{'disable': disable}" + name="{{formulaire.name}}" /> + </div> + <div ng-if="!actiononchange"> + <input class="form-control input-sm" + ng-if="forms[formulaire.name].type == 'TextBox'" + ng-enter="action()" + ng-model="params[formulaire.name]" + ng-class="{'disable': disable}" + name="{{formulaire.name}}" /> + </div> + <div ng-if="actiononchange === true"> + <select class="form-control input-sm" + ng-if="forms[formulaire.name].type == 'Select'" + ng-change="action()" + ng-model="params[formulaire.name]" + ng-class="{'disable': disable}" + name="{{formulaire.name}}" + ng-options="option.value as (option.displayName||option.value) for option in forms[formulaire.name].options"> + </select> + </div> + <div ng-if="!actiononchange"> + <select class="form-control input-sm" + ng-if="forms[formulaire.name].type == 'Select'" + ng-enter="action()" + ng-model="params[formulaire.name]" + ng-class="{'disable': disable}" + name="{{formulaire.name}}" + ng-options="option.value as (option.displayName||option.value) for option in forms[formulaire.name].options"> + </select> + </div> + <div ng-if="actiononchange === true && + forms[formulaire.name].type == 'CheckBox'"> + <label ng-repeat="option in forms[formulaire.name].options" + class="checkbox-item input-sm"> + <input type="checkbox" + ng-checked="params[formulaire.name].indexOf(option.value) > -1" + ng-class="{'disable': disable}" + ng-click="toggleCheckbox(formulaire, option, params); action()"/> {{option.displayName||option.value}} + </label> + </div> + <div ng-if="!actiononchange && + forms[formulaire.name].type == 'CheckBox'"> + <label ng-repeat="option in forms[formulaire.name].options" + class="checkbox-item input-sm"> + <input type="checkbox" + ng-checked="params[formulaire.name].indexOf(option.value) > -1" + ng-class="{'disable': disable}" + ng-enter="action()" + ng-click="toggleCheckbox(formulaire, option, params)"/> {{option.displayName||option.value}} + </label> + </div> + </div> +</form> http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.js b/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.js new file mode 100644 index 0000000..40a70eb --- /dev/null +++ b/zeppelin-web/src/app/notebook/dynamic-forms/dynamic-forms.directive.js @@ -0,0 +1,62 @@ +/* + * Licensed 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. + */ + +import './dynamic-forms.css' + +angular.module('zeppelinWebApp').directive('dynamicForms', DynamicFormDirective) + +function DynamicFormDirective($templateRequest, $compile) { + return { + restrict: 'AE', + scope: { + id: '=id', + hide: '=hide', + disable: '=disable', + actiononchange: '=actiononchange', + forms: '=forms', + params: '=params', + action: '=action', + removeaction: '=removeaction' + }, + + link: function (scope, element, attrs, controller) { + scope.loadForm = this.loadForm + scope.toggleCheckbox = this.toggleCheckbox + $templateRequest('app/notebook/dynamic-forms/dynamic-forms.directive.html').then(function (formsHtml) { + let forms = angular.element(formsHtml) + element.append(forms) + $compile(forms)(scope) + }) + }, + + loadForm: function (formulaire, params) { + let value = formulaire.defaultValue + if (params[formulaire.name]) { + value = params[formulaire.name] + } + + params[formulaire.name] = value + }, + + toggleCheckbox: function (formulaire, option, params) { + let idx = params[formulaire.name].indexOf(option.value) + if (idx > -1) { + params[formulaire.name].splice(idx, 1) + } else { + params[formulaire.name].push(option.value) + } + } + + } +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/notebook.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 456e463..d09a0b2 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -27,6 +27,9 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope, ngToast.dismiss() $scope.note = null + $scope.actionOnFormSelectionChange = true + $scope.hideForms = false + $scope.disableForms = false $scope.editorToggled = false $scope.tableToggled = false $scope.viewOnly = false @@ -1367,6 +1370,26 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope, } } + $scope.$on('saveNoteForms', function (event, data) { + $scope.note.noteForms = data.formsData.forms + $scope.note.noteParams = data.formsData.params + }) + + $scope.isShowNoteForms = function() { + if ($scope.note && !angular.equals({}, $scope.note.noteForms)) { + return true + } + return false + } + + $scope.saveNoteForms = function () { + websocketMsgSrv.saveNoteForms($scope.note) + } + + $scope.removeNoteForms = function (formName) { + websocketMsgSrv.removeNoteForms($scope.note, formName) + } + $scope.$on('$destroy', function () { angular.element(window).off('beforeunload') $scope.killSaveTimer() http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/notebook.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/notebook.html b/zeppelin-web/src/app/notebook/notebook.html index 9441f6e..f004e9b 100644 --- a/zeppelin-web/src/app/notebook/notebook.html +++ b/zeppelin-web/src/app/notebook/notebook.html @@ -119,6 +119,23 @@ limitations under the License. </div> <div class="note-jump"></div> + <div id="noteForms" ng-if="isShowNoteForms()" class="paragraph-space box"> + <div> + <h4>Note forms</h4> + </div> + <hr /> + <div> + <dynamic-forms + id="note.id" + hide="hideForms" + disable="disableForms" + actiononchange="actionOnFormSelectionChange" + forms="note.noteForms" + params="note.noteParams" + action="saveNoteForms" + removeaction="removeNoteForms"></dynamic-forms> + </div> + </div> <!-- Include the paragraphs according to the note, pass the note to init function --> <div id="{{currentParagraph.id}}_paragraphColumn_main" http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html deleted file mode 100644 index 249e7c1..0000000 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterized-query-form.html +++ /dev/null @@ -1,71 +0,0 @@ -<!-- -Licensed 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. ---> -<form id="{{paragraph.id}}_form" role="form" - ng-show="!paragraph.config.tableHide" - class=" paragraphForm form-horizontal row"> - <div class="form-group col-sm-6 col-md-6 col-lg-4" - ng-repeat="formulaire in paragraph.settings.forms | toArray" - ng-init="loadForm(formulaire, paragraph.settings.params)"> - <label class="control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label> - <div> - <input class="form-control input-sm" - ng-if="paragraph.settings.forms[formulaire.name].type == 'TextBox'" - ng-enter="runParagraphFromButton(getEditorValue())" - ng-model="paragraph.settings.params[formulaire.name]" - ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" - name="{{formulaire.name}}" /> - </div> - <div ng-if="paragraph.config.runOnSelectionChange == true"> - <select class="form-control input-sm" - ng-if="paragraph.settings.forms[formulaire.name].type == 'Select'" - ng-change="runParagraphFromButton(getEditorValue())" - ng-model="paragraph.settings.params[formulaire.name]" - ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" - name="{{formulaire.name}}" - ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options"> - </select> - </div> - <div ng-if="paragraph.config.runOnSelectionChange == false"> - <select class="form-control input-sm" - ng-if="paragraph.settings.forms[formulaire.name].type == 'Select'" - ng-enter="runParagraphFromButton(getEditorValue())" - ng-model="paragraph.settings.params[formulaire.name]" - ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" - name="{{formulaire.name}}" - ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options"> - </select> - </div> - <div ng-if="paragraph.config.runOnSelectionChange == true && - paragraph.settings.forms[formulaire.name].type == 'CheckBox'"> - <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options" - class="checkbox-item input-sm"> - <input type="checkbox" - ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" - ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1" - ng-click="toggleCheckbox(formulaire, option, false); runParagraphFromButton(getEditorValue())"/> {{option.displayName||option.value}} - </label> - </div> - <div ng-if="paragraph.config.runOnSelectionChange == false && - paragraph.settings.forms[formulaire.name].type == 'CheckBox'"> - <label ng-repeat="option in paragraph.settings.forms[formulaire.name].options" - class="checkbox-item input-sm"> - <input type="checkbox" - ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }" - ng-checked="paragraph.settings.params[formulaire.name].indexOf(option.value) > -1" - ng-enter="runParagraphFromButton(getEditorValue())" - ng-click="toggleCheckbox(formulaire, option, false)"/> {{option.displayName||option.value}} - </label> - </div> - </div> -</form> http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index 7d95d3b..c578841 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -466,9 +466,9 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca $scope.runParagraph(paragraphText, true, false) } - $scope.runParagraphFromButton = function (paragraphText) { + $scope.runParagraphFromButton = function () { // we come here from the view, so we don't need to call `$digest()` - $scope.runParagraph(paragraphText, false, false) + $scope.runParagraph($scope.getEditorValue(), false, false) } $scope.turnOnAutoRun = function (paragraph) { @@ -657,24 +657,6 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca commitParagraph(paragraph) } - $scope.loadForm = function (formulaire, params) { - let value = formulaire.defaultValue - if (params[formulaire.name]) { - value = params[formulaire.name] - } - - $scope.paragraph.settings.params[formulaire.name] = value - } - - $scope.toggleCheckbox = function (formulaire, option) { - let idx = $scope.paragraph.settings.params[formulaire.name].indexOf(option.value) - if (idx > -1) { - $scope.paragraph.settings.params[formulaire.name].splice(idx, 1) - } else { - $scope.paragraph.settings.params[formulaire.name].push(option.value) - } - } - $scope.aceChanged = function (_, editor) { let session = editor.getSession() let dirtyText = session.getValue() http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js index 29b203c..94230de 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.test.js @@ -34,7 +34,7 @@ describe('Controller: ParagraphCtrl', function () { let functions = ['isRunning', 'getIframeDimensions', 'cancelParagraph', 'runParagraph', 'saveParagraph', 'moveUp', 'moveDown', 'insertNew', 'removeParagraph', 'toggleEditor', 'closeEditor', 'openEditor', 'closeTable', 'openTable', 'showTitle', 'hideTitle', 'setTitle', 'showLineNumbers', 'hideLineNumbers', - 'changeColWidth', 'columnWidthClass', 'toggleOutput', 'loadForm', + 'changeColWidth', 'columnWidthClass', 'toggleOutput', 'aceChanged', 'aceLoaded', 'getEditorValue', 'getProgress', 'getExecutionTime', 'isResultOutdated'] functions.forEach(function (fn) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/paragraph/paragraph.css ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.css b/zeppelin-web/src/app/notebook/paragraph/paragraph.css index a0bf299..b17272b 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.css +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.css @@ -304,28 +304,6 @@ table.table-shortcut { } /* - Paragraph Forms CSS -*/ - -.paragraphForm.form-horizontal .form-group { - margin-right: 0; - margin-left: 0; -} - -.paragraphForm.form-horizontal .form-group label { - padding-left: 0; -} - -.paragraphForm.form-horizontal .form-group .checkbox-item { - padding-left: 0; - padding-right: 10px; -} - -.paragraphForm.form-horizontal .form-group .checkbox-item input { - margin-right: 2px; -} - -/* Ace Text Editor CSS */ http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/app/notebook/paragraph/paragraph.html ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.html b/zeppelin-web/src/app/notebook/paragraph/paragraph.html index f80fb53..10afd17 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.html +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.html @@ -49,7 +49,16 @@ limitations under the License. </div> <div ng-include src="'app/notebook/paragraph/paragraph-progress-bar.html'"></div> - <div ng-include src="'app/notebook/paragraph/paragraph-parameterized-query-form.html'"></div> + <div> + <dynamic-forms + id="paragraph.id" + hide="paragraph.config.tableHide" + disable="paragraph.status == 'RUNNING' || paragraph.status == 'PENDING'" + actiononchange="paragraph.config.runOnSelectionChange" + forms="paragraph.settings.forms" + params="paragraph.settings.params" + action="runParagraphFromButton"></dynamic-forms> + </div> <!-- Rendering --> <div class="tableDisplay" http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/components/websocket/websocket-event.factory.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/websocket/websocket-event.factory.js b/zeppelin-web/src/components/websocket/websocket-event.factory.js index d4bfadf..70d61ec 100644 --- a/zeppelin-web/src/components/websocket/websocket-event.factory.js +++ b/zeppelin-web/src/components/websocket/websocket-event.factory.js @@ -142,6 +142,8 @@ function WebsocketEventFactory ($rootScope, $websocket, $location, baseUrlSrv) { $rootScope.$broadcast('noteRevisionForCompare', data) } else if (op === 'INTERPRETER_BINDINGS') { $rootScope.$broadcast('interpreterBindings', data) + } else if (op === 'SAVE_NOTE_FORMS') { + $rootScope.$broadcast('saveNoteForms', data) } else if (op === 'ERROR_INFO') { BootstrapDialog.show({ closable: false, http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/components/websocket/websocket-message.service.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/websocket/websocket-message.service.js b/zeppelin-web/src/components/websocket/websocket-message.service.js index ab97fa8..cd65e1d 100644 --- a/zeppelin-web/src/components/websocket/websocket-message.service.js +++ b/zeppelin-web/src/components/websocket/websocket-message.service.js @@ -351,5 +351,23 @@ function WebsocketMessageService ($rootScope, websocketEvents) { websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'}) }, + saveNoteForms: function (note) { + websocketEvents.sendNewEvent({op: 'SAVE_NOTE_FORMS', + data: { + noteId: note.id, + noteParams: note.noteParams + } + }) + }, + + removeNoteForms: function (note, formName) { + websocketEvents.sendNewEvent({op: 'REMOVE_NOTE_FORMS', + data: { + noteId: note.id, + formName: formName + } + }) + } + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-web/src/index.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/index.js b/zeppelin-web/src/index.js index ed8f1d8..4c41336 100644 --- a/zeppelin-web/src/index.js +++ b/zeppelin-web/src/index.js @@ -58,6 +58,7 @@ import './app/search/result-list.controller.js' import './app/search/search.service.js' import './app/helium' import './app/helium/helium.service.js' +import './app/notebook/dynamic-forms/dynamic-forms.directive.js' import './components/array-ordering/array-ordering.service.js' import './components/navbar/navbar.controller.js' import './components/navbar/expand-collapse/expand-collapse.directive.js' http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/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 13fe46a..8964210 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 @@ -238,11 +238,15 @@ public class RemoteInterpreter extends Interpreter { context.getConfig().clear(); context.getConfig().putAll(remoteConfig); GUI currentGUI = context.getGui(); + GUI currentNoteGUI = context.getNoteGui(); if (form == FormType.NATIVE) { GUI remoteGui = GUI.fromJson(remoteResult.getGui()); + GUI remoteNoteGui = GUI.fromJson(remoteResult.getNoteGui()); currentGUI.clear(); currentGUI.setParams(remoteGui.getParams()); currentGUI.setForms(remoteGui.getForms()); + currentNoteGUI.setParams(remoteNoteGui.getParams()); + currentNoteGUI.setForms(remoteNoteGui.getForms()); } else if (form == FormType.SIMPLE) { final Map<String, Input> currentForms = currentGUI.getForms(); final Map<String, Object> currentParams = currentGUI.getParams(); @@ -403,7 +407,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()), ic.getGui().toJson(), gson.toJson(ic.getRunners())); + gson.toJson(ic.getConfig()), ic.getGui().toJson(), gson.toJson(ic.getNoteGui()), + gson.toJson(ic.getRunners())); } private InterpreterResult convert(RemoteInterpreterResult result) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/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 9fb0f0e..6e66732 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 @@ -74,6 +74,9 @@ public class Note implements ParagraphJobListener, JsonSerializable { private String name = ""; private String id; + private Map<String, Object> noteParams = new HashMap<>(); + private LinkedHashMap<String, Input> noteForms = new LinkedHashMap<>(); + private transient ZeppelinConfiguration conf = ZeppelinConfiguration.create(); @@ -158,6 +161,22 @@ public class Note implements ParagraphJobListener, JsonSerializable { return name; } + public Map<String, Object> getNoteParams() { + return noteParams; + } + + public void setNoteParams(Map<String, Object> noteParams) { + this.noteParams = noteParams; + } + + public LinkedHashMap<String, Input> getNoteForms() { + return noteForms; + } + + public void setNoteForms(LinkedHashMap<String, Input> noteForms) { + this.noteForms = noteForms; + } + public String getNameWithoutPath() { String notePath = getName(); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/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 6a0c27a..10a8548 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 @@ -408,14 +408,28 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable { if (interpreter.getFormType() == FormType.NATIVE) { settings.clear(); } else if (interpreter.getFormType() == FormType.SIMPLE) { - // inputs will be built from script scriptText - LinkedHashMap<String, Input> inputs = Input.extractSimpleQueryForm(this.scriptText); + // inputs will be built from script body + LinkedHashMap<String, Input> inputs = Input.extractSimpleQueryForm(script, false); + LinkedHashMap<String, Input> noteInputs = Input.extractSimpleQueryForm(script, true); final AngularObjectRegistry angularRegistry = interpreter.getInterpreterGroup().getAngularObjectRegistry(); - String scriptBody = extractVariablesFromAngularRegistry(this.scriptText, inputs, - angularRegistry); + String scriptBody = extractVariablesFromAngularRegistry(script, inputs, angularRegistry); + settings.setForms(inputs); - script = Input.getSimpleQuery(settings.getParams(), scriptBody); + if (!noteInputs.isEmpty()) { + if (!note.getNoteForms().isEmpty()) { + Map<String, Input> currentNoteForms = note.getNoteForms(); + for (String s : noteInputs.keySet()) { + if (!currentNoteForms.containsKey(s)) { + currentNoteForms.put(s, noteInputs.get(s)); + } + } + } else { + note.setNoteForms(noteInputs); + } + } + script = Input.getSimpleQuery(note.getNoteParams(), scriptBody, true); + script = Input.getSimpleQuery(settings.getParams(), script, false); } logger.debug("RUN : " + script); try { @@ -423,6 +437,11 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable { InterpreterContext.set(context); InterpreterResult ret = interpreter.interpret(script, context); + if (interpreter.getFormType() == FormType.NATIVE) { + note.setNoteParams(context.getNoteGui().getParams()); + note.setNoteForms(context.getNoteGui().getForms()); + } + if (Code.KEEP_PREVIOUS_RESULT == ret.code()) { return getReturn(); } @@ -545,8 +564,8 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable { InterpreterContext interpreterContext = new InterpreterContext(note.getId(), getId(), intpText, this.getTitle(), - this.getText(), this.getAuthenticationInfo(), this.getConfig(), this.settings, registry, - resourcePool, runners, output); + this.getText(), this.getAuthenticationInfo(), this.getConfig(), this.settings, + getNoteGui(), registry, resourcePool, runners, output); return interpreterContext; } @@ -575,13 +594,12 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable { InterpreterContext interpreterContext = new InterpreterContext(note.getId(), getId(), intpText, this.getTitle(), - this.getText(), this.getAuthenticationInfo(), this.getConfig(), this.settings, registry, - resourcePool, runners, output); + this.getText(), this.getAuthenticationInfo(), this.getConfig(), this.settings, + getNoteGui(), registry, resourcePool, runners, output); return interpreterContext; } public InterpreterContextRunner getInterpreterContextRunner() { - return new ParagraphRunner(note, note.getId(), getId()); } @@ -743,6 +761,13 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable { return runtimeInfos; } + private GUI getNoteGui() { + GUI gui = new GUI(); + gui.setParams(this.note.getNoteParams()); + gui.setForms(this.note.getNoteForms()); + return gui; + } + @Override public boolean equals(Object o) { if (this == o) { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/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 d99bd59..82d96ae 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 @@ -182,8 +182,10 @@ public class Message implements JsonSerializable { NOTE_UPDATED, // [s-c] paragraph updated(name, config) RUN_ALL_PARAGRAPHS, // [c-s] run all paragraphs PARAGRAPH_EXECUTED_BY_SPELL, // [c-s] paragraph was executed by spell - RUN_PARAGRAPH_USING_SPELL, // [s-c] run paragraph using spell - PARAS_INFO // [s-c] paragraph runtime infos + RUN_PARAGRAPH_USING_SPELL, // [s-c] run paragraph using spell + PARAS_INFO, // [s-c] paragraph runtime infos + SAVE_NOTE_FORMS, // save note forms + REMOVE_NOTE_FORMS // remove note forms } private static final Gson gson = new Gson(); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java index 971f376..329cb7a 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java @@ -56,7 +56,7 @@ public class TimeoutLifecycleManagerTest extends AbstractInterpreterTest { RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.echo"); InterpreterContext context = new InterpreterContext("noteId", "paragraphId", "repl", "title", "text", AuthenticationInfo.ANONYMOUS, new HashMap<String, Object>(), new GUI(), - null, null, new ArrayList<InterpreterContextRunner>(), null); + new GUI(), null, null, new ArrayList<InterpreterContextRunner>(), null); remoteInterpreter.interpret("hello world", context); assertTrue(remoteInterpreter.isOpened()); InterpreterSetting interpreterSetting = interpreterSettingManager.getInterpreterSettingByName("test"); @@ -95,7 +95,7 @@ public class TimeoutLifecycleManagerTest extends AbstractInterpreterTest { protected Object jobRun() throws Throwable { InterpreterContext context = new InterpreterContext("noteId", "paragraphId", "repl", "title", "text", AuthenticationInfo.ANONYMOUS, new HashMap<String, Object>(), new GUI(), - null, null, new ArrayList<InterpreterContextRunner>(), null); + new GUI(), null, null, new ArrayList<InterpreterContextRunner>(), null); return remoteInterpreter.interpret("100000", context); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java index 54814c4..658fda3 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java @@ -86,6 +86,7 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener { new AuthenticationInfo(), new HashMap<String, Object>(), new GUI(), + new GUI(), new AngularObjectRegistry(intp.getInterpreterGroup().getId(), null), new LocalResourcePool("pool1"), new LinkedList<InterpreterContextRunner>(), null); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/50cfabdf/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java index f52803d..fa2aa42 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java @@ -76,6 +76,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce new AuthenticationInfo(), new HashMap<String, Object>(), new GUI(), + new GUI(), null, null, new LinkedList<InterpreterContextRunner>(), null);
