Google calendar

Monday 25 April 2016

Week 1 - XmlNotebookRepo (Store Notebooks in XML format)

 Goal

The goal would be to have .xml representation of the notebook persisted in local filesystem along with existing .json one. Could be just note.xml in the same folder, or could be `./notebook-xml/<noteId>/note.xml`
It should save the same notebook, but in XML format, just in the local filesystem.

So here is how I approached..
  • Created XmlNotebookRepo java class in package org.zeppelin.notebook.repo; copied code from VFSNotebookRepo changed the storage directory at this line
    this.filesystemRoot = new URI(new File(
            conf.getRelativeDir(filesystemRoot.getPath() + "-xml")).getAbsolutePath()); 
  •  Added the following in zeppelin-site.xml
    <property>
            <name>zeppelin.notebook.storage</name>
            <value>org.apache.zeppelin.notebook.repo.XmlNotebookRepo</value>
            <description>notebook persistence layer implementation</description>
    </property> 
    
    
  • So now zeppelin.notebook.storage would have two properties but while remote debugging I found that it has only one value. I also tried uncommenting the GitNotebookRepo storage property but still the value was one.

    the allStorageClassNames variable did not contain comma separated class names.
So I proceeded with  the XmlNotebookRepo itself.

JAXB Usage

I read and created some JAXB examples created some Employee, Student, Address examples with composition.Generated the XML output, different types of annotations @XmlRootElement , @XmlElementWrapper , @XmlElement , @XmlAccessorType(XmlAccessType.FIELD) @XmlTransient etc. This blog[1] was quite useful.
  1. A no-arg constructor is required. 
  2. Public getter/setter or @XmlElement 
  3. Also java collection are mapped to Xml like Map,List,Set. @XmlElementWrapper to create a wrapping element. 

Mapping of Interfaces.

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions java.util.List is an interface, and JAXB can't handle interfaces 

The solution to this is to use @XmlAnyElement with @XmlRootElement and passing .class of the classes that implement it to JAXBContext.newInstance. Here is the code to demonstrate. Here are the following classes[2]
  1. Address.java 
  2. Cow.java
  3. Employee.java
  4. Student.java
  5. XMLTest.java
Now moving to zeppelin, Modifying Note.java with the annotations, also Paragraph.java needs to modified but I thought lets start first with simple fields to mapped and later move to complex members like AngularObjects, paragraphs, config, Info.
Fields like NoteInterpreterLoader, JobListenerFactory , NotebookRepo have to be transient , we don't want them to be mapped in XML file so I used the annotation @XmlTransient and still I am getting error at this line in XmlNotebookRepo save() method.
Please help.. I have spent a day solving this I don't know how to proceed further. 
Before running the server again please delete the note in  notebook-xml as I have not handled loadallNotes() which loads all saved notes. Breakpoint is at save method in XmlNotebookrepo which is hit after creating Note in the UI.

Errors are temporary, giving up is permanent

So I have figured out what was wrong. I read about XmlAccessorTypes like Field,Property and Public and also XmlAdapters. Now I have my Note saved in Xml partially AngularObjects and GUI-config is remaining and loading of notes i.e unmarshalling.

working ...

Links