diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template index 77e0b1f3bcd..9c44e47bea0 100755 --- a/conf/zeppelin-site.xml.template +++ b/conf/zeppelin-site.xml.template @@ -49,6 +49,12 @@ path or URI for notebook persist + + zeppelin.notebook.peruser.notes + false + Set this to true to have separated user spaces (e.g. one folder per user) + + zeppelin.notebook.homescreen @@ -176,6 +182,12 @@ Interpreter implementation base directory + + zeppelin.interpreter.peruser.factories + false + Set to true to have separated interperter factory per user + + zeppelin.interpreter.localRepo local-repo diff --git a/notebook/2A94M5J1Z/note.json b/notebook/2A94M5J1Z/note.json deleted file mode 100644 index 5687785d99c..00000000000 --- a/notebook/2A94M5J1Z/note.json +++ /dev/null @@ -1,347 +0,0 @@ -{ - "paragraphs": [ - { - "text": "%md\n## Welcome to Zeppelin.\n##### This is a live tutorial, you can run the code yourself. (Shift-Enter to Run)", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "editorHide": true - }, - "settings": { - "params": {}, - "forms": {} - }, - "jobName": "paragraph_1423836981412_-1007008116", - "id": "20150213-231621_168813393", - "result": { - "code": "SUCCESS", - "type": "HTML", - "msg": "\u003ch2\u003eWelcome to Zeppelin.\u003c/h2\u003e\n\u003ch5\u003eThis is a live tutorial, you can run the code yourself. (Shift-Enter to Run)\u003c/h5\u003e\n" - }, - "dateCreated": "Feb 13, 2015 11:16:21 PM", - "dateStarted": "Apr 1, 2015 9:11:09 PM", - "dateFinished": "Apr 1, 2015 9:11:10 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "title": "Load data into table", - "text": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\n\n// Zeppelin creates and injects sc (SparkContext) and sqlContext (HiveContext or SqlContext)\n// So you don\u0027t need create them manually\n\n// load bank data\nval bankText \u003d sc.parallelize(\n IOUtils.toString(\n new URL(\"https://s3.amazonaws.com/apache-zeppelin/tutorial/bank/bank.csv\"),\n Charset.forName(\"utf8\")).split(\"\\n\"))\n\ncase class Bank(age: Integer, job: String, marital: String, education: String, balance: Integer)\n\nval bank \u003d bankText.map(s \u003d\u003e s.split(\";\")).filter(s \u003d\u003e s(0) !\u003d \"\\\"age\\\"\").map(\n s \u003d\u003e Bank(s(0).toInt, \n s(1).replaceAll(\"\\\"\", \"\"),\n s(2).replaceAll(\"\\\"\", \"\"),\n s(3).replaceAll(\"\\\"\", \"\"),\n s(5).replaceAll(\"\\\"\", \"\").toInt\n )\n).toDF()\nbank.registerTempTable(\"bank\")", - "dateUpdated": "Jan 14, 2016 7:58:56 PM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "title": true, - "enabled": true, - "editorMode": "ace/mode/scala" - }, - "settings": { - "params": {}, - "forms": {} - }, - "jobName": "paragraph_1423500779206_-1502780787", - "id": "20150210-015259_1403135953", - "result": { - "code": "SUCCESS", - "type": "TEXT", - "msg": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\nbankText: org.apache.spark.rdd.RDD[String] \u003d ParallelCollectionRDD[32] at parallelize at \u003cconsole\u003e:65\ndefined class Bank\nbank: org.apache.spark.sql.DataFrame \u003d [age: int, job: string, marital: string, education: string, balance: int]\n" - }, - "dateCreated": "Feb 10, 2015 1:52:59 AM", - "dateStarted": "Jul 3, 2015 1:43:40 PM", - "dateFinished": "Jul 3, 2015 1:43:45 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%sql \nselect age, count(1) value\nfrom bank \nwhere age \u003c 30 \ngroup by age \norder by age", - "config": { - "colWidth": 4.0, - "graph": { - "mode": "multiBarChart", - "height": 300.0, - "optionOpen": false, - "keys": [ - { - "name": "age", - "index": 0.0, - "aggr": "sum" - } - ], - "values": [ - { - "name": "value", - "index": 1.0, - "aggr": "sum" - } - ], - "groups": [], - "scatter": { - "xAxis": { - "name": "age", - "index": 0.0, - "aggr": "sum" - }, - "yAxis": { - "name": "value", - "index": 1.0, - "aggr": "sum" - } - } - } - }, - "settings": { - "params": {}, - "forms": {} - }, - "jobName": "paragraph_1423500782552_-1439281894", - "id": "20150210-015302_1492795503", - "result": { - "code": "SUCCESS", - "type": "TABLE", - "msg": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n" - }, - "dateCreated": "Feb 10, 2015 1:53:02 AM", - "dateStarted": "Jul 3, 2015 1:43:17 PM", - "dateFinished": "Jul 3, 2015 1:43:23 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere age \u003c ${maxAge\u003d30} \ngroup by age \norder by age", - "config": { - "colWidth": 4.0, - "graph": { - "mode": "multiBarChart", - "height": 300.0, - "optionOpen": false, - "keys": [ - { - "name": "age", - "index": 0.0, - "aggr": "sum" - } - ], - "values": [ - { - "name": "value", - "index": 1.0, - "aggr": "sum" - } - ], - "groups": [], - "scatter": { - "xAxis": { - "name": "age", - "index": 0.0, - "aggr": "sum" - }, - "yAxis": { - "name": "value", - "index": 1.0, - "aggr": "sum" - } - } - } - }, - "settings": { - "params": { - "maxAge": "35" - }, - "forms": { - "maxAge": { - "name": "maxAge", - "defaultValue": "30", - "hidden": false - } - } - }, - "jobName": "paragraph_1423720444030_-1424110477", - "id": "20150212-145404_867439529", - "result": { - "code": "SUCCESS", - "type": "TABLE", - "msg": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n30\t150\n31\t199\n32\t224\n33\t186\n34\t231\n" - }, - "dateCreated": "Feb 12, 2015 2:54:04 PM", - "dateStarted": "Jul 3, 2015 1:43:28 PM", - "dateFinished": "Jul 3, 2015 1:43:29 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere marital\u003d\"${marital\u003dsingle,single|divorced|married}\" \ngroup by age \norder by age", - "config": { - "colWidth": 4.0, - "graph": { - "mode": "multiBarChart", - "height": 300.0, - "optionOpen": false, - "keys": [ - { - "name": "age", - "index": 0.0, - "aggr": "sum" - } - ], - "values": [ - { - "name": "value", - "index": 1.0, - "aggr": "sum" - } - ], - "groups": [], - "scatter": { - "xAxis": { - "name": "age", - "index": 0.0, - "aggr": "sum" - }, - "yAxis": { - "name": "value", - "index": 1.0, - "aggr": "sum" - } - } - } - }, - "settings": { - "params": { - "marital": "single" - }, - "forms": { - "marital": { - "name": "marital", - "defaultValue": "single", - "options": [ - { - "value": "single" - }, - { - "value": "divorced" - }, - { - "value": "married" - } - ], - "hidden": false - } - } - }, - "jobName": "paragraph_1423836262027_-210588283", - "id": "20150213-230422_1600658137", - "result": { - "code": "SUCCESS", - "type": "TABLE", - "msg": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t17\n24\t13\n25\t33\n26\t56\n27\t64\n28\t78\n29\t56\n30\t92\n31\t86\n32\t105\n33\t61\n34\t75\n35\t46\n36\t50\n37\t43\n38\t44\n39\t30\n40\t25\n41\t19\n42\t23\n43\t21\n44\t20\n45\t15\n46\t14\n47\t12\n48\t12\n49\t11\n50\t8\n51\t6\n52\t9\n53\t4\n55\t3\n56\t3\n57\t2\n58\t7\n59\t2\n60\t5\n66\t2\n69\t1\n" - }, - "dateCreated": "Feb 13, 2015 11:04:22 PM", - "dateStarted": "Jul 3, 2015 1:43:33 PM", - "dateFinished": "Jul 3, 2015 1:43:34 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "editorHide": true - }, - "settings": { - "params": {}, - "forms": {} - }, - "jobName": "paragraph_1423836268492_216498320", - "id": "20150213-230428_1231780373", - "result": { - "code": "SUCCESS", - "type": "HTML", - "msg": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n" - }, - "dateCreated": "Feb 13, 2015 11:04:28 PM", - "dateStarted": "Apr 1, 2015 9:12:18 PM", - "dateFinished": "Apr 1, 2015 9:12:18 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n This dataset is public available for research. The details are described in [Moro et al., 2011]. \n Please include this citation if you plan to use this database:\n\n [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n Available at: [pdf] http://hdl.handle.net/1822/14838\n [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "editorHide": true - }, - "settings": { - "params": {}, - "forms": {} - }, - "jobName": "paragraph_1427420818407_872443482", - "id": "20150326-214658_12335843", - "result": { - "code": "SUCCESS", - "type": "HTML", - "msg": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n This dataset is public available for research. The details are described in [Moro et al., 2011]. \n Please include this citation if you plan to use this database:\n\n [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n Available at: [pdf] http://hdl.handle.net/1822/14838\n [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n" - }, - "dateCreated": "Mar 26, 2015 9:46:58 PM", - "dateStarted": "Jul 3, 2015 1:44:56 PM", - "dateFinished": "Jul 3, 2015 1:44:56 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "config": {}, - "settings": { - "params": {}, - "forms": {} - }, - "jobName": "paragraph_1435955447812_-158639899", - "id": "20150703-133047_853701097", - "dateCreated": "Jul 3, 2015 1:30:47 PM", - "status": "READY", - "progressUpdateIntervalMs": 500 - } - ], - "name": "Zeppelin Tutorial", - "id": "2A94M5J1Z", - "angularObjects": { - "2B6FF8NNU": [], - "2B67PH63Z": [] - }, - "config": { - "looknfeel": "default" - }, - "info": {} -} \ No newline at end of file diff --git a/notebook/2BQA35CJZ/note.json b/notebook/2BQA35CJZ/note.json deleted file mode 100644 index 5c6e75183f0..00000000000 --- a/notebook/2BQA35CJZ/note.json +++ /dev/null @@ -1,271 +0,0 @@ -{ - "paragraphs": [ - { - "text": "%md\n\n### Pre-requests\nnumpy, matplotlib are installed \n\n### os x\nmake sure locale is set, to avoid `ValueError: unknown locale: UTF-8`\n\n### virtualenv\nIn case you want to use virtualenv:\n - configure python interpreter property -\u003e `absolute/path/to/venv/bin/python`\n - see *Working with Matplotlib in Virtual environments* in the [Matplotlib FAQ](http://matplotlib.org/faq/virtualenv_faq.html)", - "dateUpdated": "Jun 22, 2016 5:31:34 AM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/markdown", - "editorHide": true, - "tableHide": false - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1465894017761_505669129", - "id": "20160614-174657_1772993700", - "result": { - "code": "SUCCESS", - "type": "HTML", - "msg": "\u003ch3\u003ePre-requests\u003c/h3\u003e\n\u003cp\u003enumpy, matplotlib are installed\u003c/p\u003e\n\u003ch3\u003eos x\u003c/h3\u003e\n\u003cp\u003emake sure locale is set, to avoid \u003ccode\u003eValueError: unknown locale: UTF-8\u003c/code\u003e\u003c/p\u003e\n\u003ch3\u003evirtualenv\u003c/h3\u003e\n\u003cp\u003eIn case you want to use virtualenv:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003econfigure python interpreter property -\u003e \u003ccode\u003eabsolute/path/to/venv/bin/python\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003esee \u003cem\u003eWorking with Matplotlib in Virtual environments\u003c/em\u003e in the \u003ca href\u003d\"http://matplotlib.org/faq/virtualenv_faq.html\"\u003eMatplotlib FAQ\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n" - }, - "dateCreated": "Jun 14, 2016 5:46:57 AM", - "dateStarted": "Jun 22, 2016 5:31:34 AM", - "dateFinished": "Jun 22, 2016 5:31:34 AM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%python\nimport numpy as np\nimport matplotlib.pyplot as plt", - "dateUpdated": "Jun 22, 2016 5:31:34 AM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/scala" - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1466090491493_2078041104", - "id": "20160617-002131_1552178409", - "result": { - "code": "SUCCESS", - "type": "TEXT", - "msg": "" - }, - "dateCreated": "Jun 17, 2016 12:21:31 PM", - "dateStarted": "Jun 22, 2016 5:31:34 AM", - "dateFinished": "Jun 22, 2016 5:31:35 AM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%python\ndef f(x):\n return np.cos(1/x)\n\nx \u003d np.linspace(-2, 2, 1000)", - "dateUpdated": "Jun 22, 2016 5:31:34 AM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/scala", - "editorHide": false, - "tableHide": false - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1465893861414_-1641861313", - "id": "20160614-174421_274483707", - "result": { - "code": "SUCCESS", - "type": "TEXT", - "msg": "" - }, - "dateCreated": "Jun 14, 2016 5:44:21 AM", - "dateStarted": "Jun 22, 2016 5:31:35 AM", - "dateFinished": "Jun 22, 2016 5:31:35 AM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%python\n\nplt.figure()\nplt.plot(x, f(x), lw\u003d2)\nz.show(plt, width\u003d\u0027500px\u0027)\nplt.close()", - "dateUpdated": "Jun 22, 2016 5:31:34 AM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/scala" - }, - "settings": { - "params": { - "f1": "defaultValue" - }, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1466088587936_-914466845", - "id": "20160616-234947_579056637", - "result": { - "code": "SUCCESS", - "type": "HTML", - "msg": "\u003cdiv style\u003d\u0027width:500px\u0027\u003e\u003c?xml version\u003d\"1.0\" encoding\u003d\"utf-8\" standalone\u003d\"no\"?\u003e\n\r\u003c!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n\r \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"\u003e\n\r\u003c!-- Created with matplotlib (http://matplotlib.org/) --\u003e\n\r\u003csvg height\u003d\"432pt\" version\u003d\"1.1\" viewBox\u003d\"0 0 576 432\" width\u003d\"576pt\" xmlns\u003d\"http://www.w3.org/2000/svg\" xmlns:xlink\u003d\"http://www.w3.org/1999/xlink\"\u003e\n\r \u003cdefs\u003e\n\r \u003cstyle type\u003d\"text/css\"\u003e\n\r*{stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:100000;}\n\r \u003c/style\u003e\n\r \u003c/defs\u003e\n\r \u003cg id\u003d\"figure_1\"\u003e\n\r \u003cg id\u003d\"patch_1\"\u003e\n\r \u003cpath d\u003d\"M 0 432 \n\rL 576 432 \n\rL 576 0 \n\rL 0 0 \n\rz\n\r\" style\u003d\"fill:#ffffff;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"axes_1\"\u003e\n\r \u003cg id\u003d\"patch_2\"\u003e\n\r \u003cpath d\u003d\"M 72 388.8 \n\rL 518.4 388.8 \n\rL 518.4 43.2 \n\rL 72 43.2 \n\rz\n\r\" style\u003d\"fill:#ffffff;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_1\"\u003e\n\r \u003cpath clip-path\u003d\"url(#p8d9001317b)\" d\u003d\"M 72 64.353733 \n\rL 81.383784 66.208006 \n\rL 89.873874 68.102082 \n\rL 97.917117 70.118515 \n\rL 105.513514 72.253983 \n\rL 112.663063 74.501874 \n\rL 119.365766 76.851708 \n\rL 125.621622 79.288583 \n\rL 131.430631 81.792703 \n\rL 136.792793 84.33905 \n\rL 142.154955 87.14138 \n\rL 147.07027 89.964621 \n\rL 151.538739 92.769201 \n\rL 156.007207 95.828137 \n\rL 160.475676 99.172274 \n\rL 164.497297 102.455067 \n\rL 168.518919 106.027174 \n\rL 172.540541 109.922371 \n\rL 176.115315 113.687089 \n\rL 179.69009 117.76831 \n\rL 183.264865 122.200833 \n\rL 186.83964 127.024032 \n\rL 189.967568 131.599727 \n\rL 193.095495 136.542179 \n\rL 196.223423 141.888876 \n\rL 199.351351 147.681647 \n\rL 202.479279 153.967119 \n\rL 205.607207 160.797174 \n\rL 208.735135 168.229361 \n\rL 211.863063 176.327214 \n\rL 214.544144 183.850661 \n\rL 217.225225 191.961516 \n\rL 219.906306 200.70986 \n\rL 222.587387 210.147822 \n\rL 225.268468 220.328242 \n\rL 227.94955 231.302469 \n\rL 230.630631 243.116823 \n\rL 233.758559 258.00883 \n\rL 236.886486 274.114509 \n\rL 240.014414 291.390828 \n\rL 243.589189 312.360386 \n\rL 252.079279 362.998329 \n\rL 253.866667 372.223666 \n\rL 255.207207 378.258931 \n\rL 256.547748 383.242279 \n\rL 257.441441 385.820429 \n\rL 258.335135 387.672064 \n\rL 258.781982 388.285652 \n\rL 259.228829 388.667872 \n\rL 259.675676 388.799999 \n\rL 260.122523 388.66222 \n\rL 260.569369 388.233607 \n\rL 261.016216 387.4921 \n\rL 261.463063 386.414495 \n\rL 261.90991 384.976449 \n\rL 262.803604 380.916087 \n\rL 263.697297 375.09463 \n\rL 264.590991 367.280889 \n\rL 265.484685 357.233455 \n\rL 266.378378 344.70846 \n\rL 267.272072 329.471815 \n\rL 268.165766 311.317715 \n\rL 269.506306 278.31162 \n\rL 270.846847 238.369968 \n\rL 272.634234 176.074757 \n\rL 275.315315 80.644271 \n\rL 276.209009 57.296088 \n\rL 276.655856 49.237132 \n\rL 277.102703 44.371691 \n\rL 277.54955 43.335468 \n\rL 277.996396 46.77714 \n\rL 278.443243 55.323403 \n\rL 278.89009 69.528308 \n\rL 279.336937 89.803055 \n\rL 280.230631 148.906277 \n\rL 281.124324 228.877168 \n\rL 282.464865 352.338838 \n\rL 282.911712 378.736731 \n\rL 283.358559 388.799995 \n\rL 283.805405 377.147391 \n\rL 284.252252 340.163226 \n\rL 284.699099 278.151058 \n\rL 286.03964 55.748432 \n\rL 286.486486 48.207233 \n\rL 286.933333 113.197709 \n\rL 287.827027 361.331139 \n\rL 288.273874 374.824982 \n\rL 289.167568 53.650098 \n\rL 289.614414 142.342594 \n\rL 290.061261 382.365259 \n\rL 290.508108 177.65454 \n\rL 290.954955 146.476843 \n\rL 291.401802 293.143963 \n\rL 291.848649 269.253145 \n\rL 292.295495 86.540778 \n\rL 292.742342 191.202268 \n\rL 293.189189 129.82011 \n\rL 293.636036 323.483468 \n\rL 294.082883 76.471144 \n\rL 294.52973 388.798319 \n\rL 295.87027 388.798319 \n\rL 296.317117 76.471144 \n\rL 296.763964 323.483468 \n\rL 297.210811 129.82011 \n\rL 297.657658 191.202268 \n\rL 298.104505 86.540778 \n\rL 298.551351 269.253145 \n\rL 298.998198 293.143963 \n\rL 299.445045 146.476843 \n\rL 299.891892 177.65454 \n\rL 300.338739 382.365259 \n\rL 300.785586 142.342594 \n\rL 301.232432 53.650098 \n\rL 302.126126 374.824982 \n\rL 302.572973 361.331139 \n\rL 303.466667 113.197709 \n\rL 303.913514 48.207233 \n\rL 304.36036 55.748432 \n\rL 304.807207 115.49803 \n\rL 305.700901 278.151058 \n\rL 306.147748 340.163226 \n\rL 306.594595 377.147391 \n\rL 307.041441 388.799995 \n\rL 307.488288 378.736731 \n\rL 307.935135 352.338838 \n\rL 308.828829 272.73672 \n\rL 310.169369 148.906277 \n\rL 311.063063 89.803055 \n\rL 311.50991 69.528308 \n\rL 311.956757 55.323403 \n\rL 312.403604 46.77714 \n\rL 312.85045 43.335468 \n\rL 313.297297 44.371691 \n\rL 313.744144 49.237132 \n\rL 314.190991 57.296088 \n\rL 315.084685 80.644271 \n\rL 316.425225 126.342632 \n\rL 319.553153 238.369968 \n\rL 320.893694 278.31162 \n\rL 322.234234 311.317715 \n\rL 323.574775 337.442889 \n\rL 324.468468 351.295694 \n\rL 325.362162 362.551685 \n\rL 326.255856 371.451716 \n\rL 327.14955 378.239639 \n\rL 328.043243 383.152497 \n\rL 328.936937 386.414495 \n\rL 329.383784 387.4921 \n\rL 329.830631 388.233607 \n\rL 330.277477 388.66222 \n\rL 330.724324 388.799999 \n\rL 331.171171 388.667872 \n\rL 331.618018 388.285652 \n\rL 332.064865 387.672064 \n\rL 332.958559 385.820429 \n\rL 333.852252 383.242279 \n\rL 334.745946 380.051849 \n\rL 336.086486 374.334557 \n\rL 337.873874 365.40576 \n\rL 340.108108 352.878733 \n\rL 344.12973 328.640229 \n\rL 349.491892 296.523995 \n\rL 353.066667 276.51302 \n\rL 356.194595 260.235459 \n\rL 359.322523 245.170296 \n\rL 362.45045 231.302469 \n\rL 365.578378 218.577728 \n\rL 368.259459 208.524692 \n\rL 370.940541 199.205338 \n\rL 374.068468 189.18959 \n\rL 377.196396 180.018538 \n\rL 380.324324 171.614438 \n\rL 383.452252 163.905101 \n\rL 386.58018 156.82438 \n\rL 389.708108 150.31219 \n\rL 392.836036 144.314267 \n\rL 395.963964 138.781787 \n\rL 399.091892 133.67092 \n\rL 402.21982 128.942374 \n\rL 405.794595 123.961476 \n\rL 409.369369 119.387329 \n\rL 412.944144 115.178681 \n\rL 416.518919 111.299086 \n\rL 420.540541 107.287874 \n\rL 424.562162 103.612047 \n\rL 428.583784 100.2363 \n\rL 432.605405 97.129692 \n\rL 437.073874 93.96062 \n\rL 441.542342 91.057732 \n\rL 446.457658 88.138219 \n\rL 451.372973 85.473707 \n\rL 456.735135 82.824584 \n\rL 462.097297 80.413522 \n\rL 467.906306 78.038628 \n\rL 474.162162 75.72371 \n\rL 480.864865 73.487761 \n\rL 488.014414 71.345238 \n\rL 495.610811 69.306473 \n\rL 503.654054 67.378168 \n\rL 512.590991 65.474102 \n\rL 518.4 64.353733 \n\rL 518.4 64.353733 \n\r\" style\u003d\"fill:none;stroke:#0000ff;stroke-linecap:square;stroke-width:2.0;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"patch_3\"\u003e\n\r \u003cpath d\u003d\"M 72 43.2 \n\rL 518.4 43.2 \n\r\" style\u003d\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"patch_4\"\u003e\n\r \u003cpath d\u003d\"M 518.4 388.8 \n\rL 518.4 43.2 \n\r\" style\u003d\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"patch_5\"\u003e\n\r \u003cpath d\u003d\"M 72 388.8 \n\rL 518.4 388.8 \n\r\" style\u003d\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"patch_6\"\u003e\n\r \u003cpath d\u003d\"M 72 388.8 \n\rL 72 43.2 \n\r\" style\u003d\"fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;\"/\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"matplotlib.axis_1\"\u003e\n\r \u003cg id\u003d\"xtick_1\"\u003e\n\r \u003cg id\u003d\"line2d_2\"\u003e\n\r \u003cdefs\u003e\n\r \u003cpath d\u003d\"M 0 0 \n\rL 0 -4 \n\r\" id\u003d\"m1b33711152\" style\u003d\"stroke:#000000;stroke-width:0.5;\"/\u003e\n\r \u003c/defs\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_3\"\u003e\n\r \u003cdefs\u003e\n\r \u003cpath d\u003d\"M 0 0 \n\rL 0 4 \n\r\" id\u003d\"m5ced6e031b\" style\u003d\"stroke:#000000;stroke-width:0.5;\"/\u003e\n\r \u003c/defs\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_1\"\u003e\n\r \u003c!-- −2.0 --\u003e\n\r \u003cdefs\u003e\n\r \u003cpath d\u003d\"M 10.59375 35.5 \n\rL 73.1875 35.5 \n\rL 73.1875 27.203125 \n\rL 10.59375 27.203125 \n\rz\n\r\" id\u003d\"BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cpath d\u003d\"M 19.1875 8.296875 \n\rL 53.609375 8.296875 \n\rL 53.609375 0 \n\rL 7.328125 0 \n\rL 7.328125 8.296875 \n\rQ 12.9375 14.109375 22.625 23.890625 \n\rQ 32.328125 33.6875 34.8125 36.53125 \n\rQ 39.546875 41.84375 41.421875 45.53125 \n\rQ 43.3125 49.21875 43.3125 52.78125 \n\rQ 43.3125 58.59375 39.234375 62.25 \n\rQ 35.15625 65.921875 28.609375 65.921875 \n\rQ 23.96875 65.921875 18.8125 64.3125 \n\rQ 13.671875 62.703125 7.8125 59.421875 \n\rL 7.8125 69.390625 \n\rQ 13.765625 71.78125 18.9375 73 \n\rQ 24.125 74.21875 28.421875 74.21875 \n\rQ 39.75 74.21875 46.484375 68.546875 \n\rQ 53.21875 62.890625 53.21875 53.421875 \n\rQ 53.21875 48.921875 51.53125 44.890625 \n\rQ 49.859375 40.875 45.40625 35.40625 \n\rQ 44.1875 33.984375 37.640625 27.21875 \n\rQ 31.109375 20.453125 19.1875 8.296875 \n\r\" id\u003d\"BitstreamVeraSans-Roman-32\"/\u003e\n\r \u003cpath d\u003d\"M 31.78125 66.40625 \n\rQ 24.171875 66.40625 20.328125 58.90625 \n\rQ 16.5 51.421875 16.5 36.375 \n\rQ 16.5 21.390625 20.328125 13.890625 \n\rQ 24.171875 6.390625 31.78125 6.390625 \n\rQ 39.453125 6.390625 43.28125 13.890625 \n\rQ 47.125 21.390625 47.125 36.375 \n\rQ 47.125 51.421875 43.28125 58.90625 \n\rQ 39.453125 66.40625 31.78125 66.40625 \n\rM 31.78125 74.21875 \n\rQ 44.046875 74.21875 50.515625 64.515625 \n\rQ 56.984375 54.828125 56.984375 36.375 \n\rQ 56.984375 17.96875 50.515625 8.265625 \n\rQ 44.046875 -1.421875 31.78125 -1.421875 \n\rQ 19.53125 -1.421875 13.0625 8.265625 \n\rQ 6.59375 17.96875 6.59375 36.375 \n\rQ 6.59375 54.828125 13.0625 64.515625 \n\rQ 19.53125 74.21875 31.78125 74.21875 \n\r\" id\u003d\"BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cpath d\u003d\"M 10.6875 12.40625 \n\rL 21 12.40625 \n\rL 21 0 \n\rL 10.6875 0 \n\rz\n\r\" id\u003d\"BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003c/defs\u003e\n\r \u003cg transform\u003d\"translate(57.4303125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cuse x\u003d\"83.7890625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-32\"/\u003e\n\r \u003cuse x\u003d\"147.412109375\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"179.19921875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_2\"\u003e\n\r \u003cg id\u003d\"line2d_4\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"127.8\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_5\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"127.8\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_2\"\u003e\n\r \u003c!-- −1.5 --\u003e\n\r \u003cdefs\u003e\n\r \u003cpath d\u003d\"M 12.40625 8.296875 \n\rL 28.515625 8.296875 \n\rL 28.515625 63.921875 \n\rL 10.984375 60.40625 \n\rL 10.984375 69.390625 \n\rL 28.421875 72.90625 \n\rL 38.28125 72.90625 \n\rL 38.28125 8.296875 \n\rL 54.390625 8.296875 \n\rL 54.390625 0 \n\rL 12.40625 0 \n\rz\n\r\" id\u003d\"BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cpath d\u003d\"M 10.796875 72.90625 \n\rL 49.515625 72.90625 \n\rL 49.515625 64.59375 \n\rL 19.828125 64.59375 \n\rL 19.828125 46.734375 \n\rQ 21.96875 47.46875 24.109375 47.828125 \n\rQ 26.265625 48.1875 28.421875 48.1875 \n\rQ 40.625 48.1875 47.75 41.5 \n\rQ 54.890625 34.8125 54.890625 23.390625 \n\rQ 54.890625 11.625 47.5625 5.09375 \n\rQ 40.234375 -1.421875 26.90625 -1.421875 \n\rQ 22.3125 -1.421875 17.546875 -0.640625 \n\rQ 12.796875 0.140625 7.71875 1.703125 \n\rL 7.71875 11.625 \n\rQ 12.109375 9.234375 16.796875 8.0625 \n\rQ 21.484375 6.890625 26.703125 6.890625 \n\rQ 35.15625 6.890625 40.078125 11.328125 \n\rQ 45.015625 15.765625 45.015625 23.390625 \n\rQ 45.015625 31 40.078125 35.4375 \n\rQ 35.15625 39.890625 26.703125 39.890625 \n\rQ 22.75 39.890625 18.8125 39.015625 \n\rQ 14.890625 38.140625 10.796875 36.28125 \n\rz\n\r\" id\u003d\"BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/defs\u003e\n\r \u003cg transform\u003d\"translate(113.2303125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cuse x\u003d\"83.7890625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cuse x\u003d\"147.412109375\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"179.19921875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_3\"\u003e\n\r \u003cg id\u003d\"line2d_6\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"183.6\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_7\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"183.6\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_3\"\u003e\n\r \u003c!-- −1.0 --\u003e\n\r \u003cg transform\u003d\"translate(169.0303125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cuse x\u003d\"83.7890625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cuse x\u003d\"147.412109375\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"179.19921875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_4\"\u003e\n\r \u003cg id\u003d\"line2d_8\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"239.4\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_9\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"239.4\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_4\"\u003e\n\r \u003c!-- −0.5 --\u003e\n\r \u003cg transform\u003d\"translate(224.8303125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cuse x\u003d\"83.7890625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cuse x\u003d\"147.412109375\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"179.19921875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_5\"\u003e\n\r \u003cg id\u003d\"line2d_10\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"295.2\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_11\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"295.2\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_5\"\u003e\n\r \u003c!-- 0.0 --\u003e\n\r \u003cg transform\u003d\"translate(285.658125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_6\"\u003e\n\r \u003cg id\u003d\"line2d_12\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"351.0\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_13\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"351.0\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_6\"\u003e\n\r \u003c!-- 0.5 --\u003e\n\r \u003cg transform\u003d\"translate(341.458125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_7\"\u003e\n\r \u003cg id\u003d\"line2d_14\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"406.8\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_15\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"406.8\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_7\"\u003e\n\r \u003c!-- 1.0 --\u003e\n\r \u003cg transform\u003d\"translate(397.258125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_8\"\u003e\n\r \u003cg id\u003d\"line2d_16\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"462.6\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_17\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"462.6\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_8\"\u003e\n\r \u003c!-- 1.5 --\u003e\n\r \u003cg transform\u003d\"translate(453.058125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"xtick_9\"\u003e\n\r \u003cg id\u003d\"line2d_18\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m1b33711152\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_19\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m5ced6e031b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_9\"\u003e\n\r \u003c!-- 2.0 --\u003e\n\r \u003cg transform\u003d\"translate(508.858125 401.918125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-32\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"matplotlib.axis_2\"\u003e\n\r \u003cg id\u003d\"ytick_1\"\u003e\n\r \u003cg id\u003d\"line2d_20\"\u003e\n\r \u003cdefs\u003e\n\r \u003cpath d\u003d\"M 0 0 \n\rL 4 0 \n\r\" id\u003d\"m3c39fe74d7\" style\u003d\"stroke:#000000;stroke-width:0.5;\"/\u003e\n\r \u003c/defs\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m3c39fe74d7\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_21\"\u003e\n\r \u003cdefs\u003e\n\r \u003cpath d\u003d\"M 0 0 \n\rL -4 0 \n\r\" id\u003d\"m4564b9459b\" style\u003d\"stroke:#000000;stroke-width:0.5;\"/\u003e\n\r \u003c/defs\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m4564b9459b\" y\u003d\"388.8\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_10\"\u003e\n\r \u003c!-- −1.0 --\u003e\n\r \u003cg transform\u003d\"translate(38.860625 392.11125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cuse x\u003d\"83.7890625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cuse x\u003d\"147.412109375\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"179.19921875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"ytick_2\"\u003e\n\r \u003cg id\u003d\"line2d_22\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m3c39fe74d7\" y\u003d\"302.4\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_23\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m4564b9459b\" y\u003d\"302.4\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_11\"\u003e\n\r \u003c!-- −0.5 --\u003e\n\r \u003cg transform\u003d\"translate(38.860625 305.71125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-2212\"/\u003e\n\r \u003cuse x\u003d\"83.7890625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cuse x\u003d\"147.412109375\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"179.19921875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"ytick_3\"\u003e\n\r \u003cg id\u003d\"line2d_24\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m3c39fe74d7\" y\u003d\"216.0\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_25\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m4564b9459b\" y\u003d\"216.0\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_12\"\u003e\n\r \u003c!-- 0.0 --\u003e\n\r \u003cg transform\u003d\"translate(48.91625 219.31125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"ytick_4\"\u003e\n\r \u003cg id\u003d\"line2d_26\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m3c39fe74d7\" y\u003d\"129.6\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_27\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m4564b9459b\" y\u003d\"129.6\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_13\"\u003e\n\r \u003c!-- 0.5 --\u003e\n\r \u003cg transform\u003d\"translate(48.91625 132.91125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-35\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"ytick_5\"\u003e\n\r \u003cg id\u003d\"line2d_28\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"72.0\" xlink:href\u003d\"#m3c39fe74d7\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"line2d_29\"\u003e\n\r \u003cg\u003e\n\r \u003cuse style\u003d\"stroke:#000000;stroke-width:0.5;\" x\u003d\"518.4\" xlink:href\u003d\"#m4564b9459b\" y\u003d\"43.2\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cg id\u003d\"text_14\"\u003e\n\r \u003c!-- 1.0 --\u003e\n\r \u003cg transform\u003d\"translate(48.91625 46.51125)scale(0.12 -0.12)\"\u003e\n\r \u003cuse xlink:href\u003d\"#BitstreamVeraSans-Roman-31\"/\u003e\n\r \u003cuse x\u003d\"63.623046875\" xlink:href\u003d\"#BitstreamVeraSans-Roman-2e\"/\u003e\n\r \u003cuse x\u003d\"95.41015625\" xlink:href\u003d\"#BitstreamVeraSans-Roman-30\"/\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003c/g\u003e\n\r \u003cdefs\u003e\n\r \u003cclipPath id\u003d\"p8d9001317b\"\u003e\n\r \u003crect height\u003d\"345.6\" width\u003d\"446.4\" x\u003d\"72.0\" y\u003d\"43.2\"/\u003e\n\r \u003c/clipPath\u003e\n\r \u003c/defs\u003e\n\r\u003c/svg\u003e\n\r\u003cdiv\u003e" - }, - "dateCreated": "Jun 16, 2016 11:49:47 AM", - "dateStarted": "Jun 22, 2016 5:31:36 AM", - "dateFinished": "Jun 22, 2016 5:31:36 AM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "%python\n\n# something else", - "dateUpdated": "Jun 22, 2016 5:50:47 AM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 394.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/python" - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1466139879415_1937425297", - "id": "20160617-140439_1111727405", - "result": { - "code": "SUCCESS", - "type": "TEXT", - "msg": "" - }, - "dateCreated": "Jun 17, 2016 2:04:39 AM", - "dateStarted": "Jun 22, 2016 5:50:47 AM", - "dateFinished": "Jun 22, 2016 5:50:47 AM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "title": "Further help using build-in command", - "text": "%python\nhelp()", - "dateUpdated": "Jul 11, 2016 11:35:39 PM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/scala", - "tableHide": false, - "title": true - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1465893931031_1683462133", - "id": "20160614-174531_1529734563", - "result": { - "code": "SUCCESS", - "type": "HTML", - "msg": "\r\u003ch2\u003ePython Interpreter help\u003c/h2\u003e\n\r\u003ch3\u003ePython 2 \u0026 3 compatibility\u003c/h3\u003e\n\r\u003cp\u003eThe interpreter is compatible with Python 2 \u0026 3.\u003cbr/\u003e\n\rTo change Python version, \n\rchange in the interpreter configuration the python to the \n\rdesired version (example : python\u003d/usr/bin/python3)\u003c/p\u003e\n\r\u003ch3\u003ePython modules\u003c/h3\u003e\n\r\u003cp\u003eThe interpreter can use all modules already installed \n\r(with pip, easy_install, etc)\u003c/p\u003e\n\r\u003ch3\u003eForms\u003c/h3\u003e\n\rYou must install py4j in order to use the form feature (pip install py4j)\n\r\u003ch4\u003eInput form\u003c/h4\u003e\n\r\u003cpre\u003eprint (z.input(\"f1\",\"defaultValue\"))\u003c/pre\u003e\n\r\u003ch4\u003eSelection form\u003c/h4\u003e\n\r\u003cpre\u003eprint(z.select(\"f2\", [(\"o1\",\"1\"), (\"o2\",\"2\")],2))\u003c/pre\u003e\n\r\u003ch4\u003eCheckbox form\u003c/h4\u003e\n\r\u003cpre\u003e print(\"\".join(z.checkbox(\"f3\", [(\"o1\",\"1\"), (\"o2\",\"2\")],[\"1\"])))\u003c/pre\u003e\n\r\u003ch3\u003eMatplotlib graph\u003c/h3\u003e\n\r\u003cdiv\u003eThe interpreter can display matplotlib graph with \n\rthe function z.show()\u003c/div\u003e\n\r\u003cdiv\u003e You need to already have matplotlib module installed \n\rto use this functionality !\u003c/div\u003e\u003cbr/\u003e\n\r\u003cpre\u003eimport matplotlib.pyplot as plt\n\rplt.figure()\n\r(.. ..)\n\rz.show(plt)\n\rplt.close()\n\r\u003c/pre\u003e\n\r\u003cdiv\u003e\u003cbr/\u003e z.show function can take optional parameters \n\rto adapt graph width and height\u003c/div\u003e\n\r\u003cdiv\u003e\u003cb\u003eexample \u003c/b\u003e:\n\r\u003cpre\u003ez.show(plt,width\u003d\u002750px\u0027)\n\rz.show(plt,height\u003d\u0027150px\u0027) \u003c/pre\u003e\u003c/div\u003e\n\r\u003ch3\u003ePandas DataFrame\u003c/h3\u003e\n\r\u003cdiv\u003e You need to have Pandas module installed \n\rto use this functionality (pip install pandas) !\u003c/div\u003e\u003cbr/\u003e\n\r\n\r\u003cdiv\u003eThe interpreter can visualize Pandas DataFrame\n\rwith the function z.show()\n\r\u003cpre\u003e\n\rimport pandas as pd\n\rdf \u003d pd.read_csv(\"bank.csv\", sep\u003d\";\")\n\rz.show(df)\n\r\u003c/pre\u003e\u003c/div\u003e\n\r\n\r\u003ch3\u003eSQL over Pandas DataFrame\u003c/h3\u003e\n\r\u003cdiv\u003e You need to have Pandas\u0026Pandasql modules installed \n\rto use this functionality (pip install pandas pandasql) !\u003c/div\u003e\u003cbr/\u003e\n\r\n\r\u003cdiv\u003ePython interpreter group includes %sql interpreter that can query \n\rPandas DataFrame using SQL and visualize results using Table Display System\n\r\n\r\u003cpre\u003e\n\r%python\n\rimport pandas as pd\n\rdf \u003d pd.read_csv(\"bank.csv\", sep\u003d\";\")\n\r\u003c/pre\u003e\n\r\u003cbr /\u003e\n\r\n\r\u003cpre\u003e\n\r%python.sql\n\r%sql\n\rSELECT * from df LIMIT 5\n\r\u003c/pre\u003e\u003c/div\u003e" - }, - "dateCreated": "Jun 14, 2016 5:45:31 AM", - "dateStarted": "Jul 11, 2016 11:35:39 PM", - "dateFinished": "Jul 11, 2016 11:35:40 PM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - }, - { - "text": "", - "dateUpdated": "Jun 22, 2016 5:31:35 AM", - "config": { - "colWidth": 12.0, - "graph": { - "mode": "table", - "height": 300.0, - "optionOpen": false, - "keys": [], - "values": [], - "groups": [], - "scatter": {} - }, - "enabled": true, - "editorMode": "ace/mode/scala" - }, - "settings": { - "params": {}, - "forms": {} - }, - "apps": [], - "jobName": "paragraph_1466042618008_-234893992", - "id": "20160616-110338_941394720", - "result": { - "code": "SUCCESS", - "type": "TEXT", - "msg": "" - }, - "dateCreated": "Jun 16, 2016 11:03:38 AM", - "dateStarted": "Jun 22, 2016 5:31:36 AM", - "dateFinished": "Jun 22, 2016 5:31:36 AM", - "status": "FINISHED", - "progressUpdateIntervalMs": 500 - } - ], - "name": "Zeppelin Tutorial: Python - matplotlib basic", - "id": "2BQA35CJZ", - "lastReplName": { - "value": "python" - }, - "angularObjects": { - "2BMX349MY:shared_process": [], - "2BN9WB6KT:shared_process": [] - }, - "config": { - "looknfeel": "default" - }, - "info": {} -} diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java index de41692607a..fb40e989588 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/AuthenticationInfo.java @@ -22,6 +22,10 @@ * */ public class AuthenticationInfo { + public static final String ANONYMOUS = "anonynmous"; + public static final AuthenticationInfo + ANONYMOUS_AUTHENTICATION_INFO = new AuthenticationInfo(ANONYMOUS); + String user; String ticket; UserCredentials userCredentials; diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java index 68cffed2568..6e0d1f3b578 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/ConfigurationsRestApi.java @@ -21,6 +21,9 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.notebook.Notebook; import org.apache.zeppelin.server.JsonResponse; +import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.utils.SecurityUtils; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -37,19 +40,13 @@ @Produces("application/json") public class ConfigurationsRestApi { - private Notebook notebook; - public ConfigurationsRestApi() {} - public ConfigurationsRestApi(Notebook notebook) { - this.notebook = notebook; - } - @GET @Path("all") @ZeppelinApi public Response getAll() { - ZeppelinConfiguration conf = notebook.getConf(); + ZeppelinConfiguration conf = ZeppelinServer.conf; Map configurations = conf.dumpConfigurations(conf, new ZeppelinConfiguration.ConfigurationKeyPredicate() { @@ -71,7 +68,7 @@ public boolean apply(String key) { @Path("prefix/{prefix}") @ZeppelinApi public Response getByPrefix(@PathParam("prefix") final String prefix) { - ZeppelinConfiguration conf = notebook.getConf(); + ZeppelinConfiguration conf = notebook().getConf(); Map configurations = conf.dumpConfigurations(conf, new ZeppelinConfiguration.ConfigurationKeyPredicate() { @@ -90,4 +87,8 @@ public boolean apply(String key) { return new JsonResponse(Status.OK, "", configurations).build(); } + private Notebook notebook() { + return ZeppelinSessions.notebook(SecurityUtils.getPrincipal()); + } + } diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java index 74412c44862..57e0f45069f 100755 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/CredentialRestApi.java @@ -20,6 +20,8 @@ import com.google.common.base.Strings; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import org.apache.zeppelin.notebook.Notebook; +import org.apache.zeppelin.session.ZeppelinSessions; import org.apache.zeppelin.user.Credentials; import org.apache.zeppelin.user.UserCredentials; import org.apache.zeppelin.user.UsernamePassword; @@ -44,7 +46,7 @@ @Produces("application/json") public class CredentialRestApi { Logger logger = LoggerFactory.getLogger(CredentialRestApi.class); - private Credentials credentials; + private Gson gson = new Gson(); @Context @@ -53,10 +55,6 @@ public class CredentialRestApi { public CredentialRestApi() { } - public CredentialRestApi(Credentials credentials) { - this.credentials = credentials; - } - /** * Put User Credentials REST API * @param message - JSON with entity, username, password. @@ -78,9 +76,9 @@ public Response putCredentials(String message) throws IOException, IllegalArgume String user = SecurityUtils.getPrincipal(); logger.info("Update credentials for user {} entity {}", user, entity); - UserCredentials uc = credentials.getUserCredentials(user); + UserCredentials uc = credentials().getUserCredentials(user); uc.putUsernamePassword(entity, new UsernamePassword(username, password)); - credentials.putUserCredentials(user, uc); + credentials().putUserCredentials(user, uc); return new JsonResponse(Status.OK).build(); } @@ -95,7 +93,7 @@ public Response getCredentials(String message) throws IOException, IllegalArgumentException { String user = SecurityUtils.getPrincipal(); logger.info("getCredentials credentials for user {} ", user); - UserCredentials uc = credentials.getUserCredentials(user); + UserCredentials uc = credentials().getUserCredentials(user); return new JsonResponse(Status.OK, uc).build(); } @@ -110,7 +108,7 @@ public Response removeCredentials(String message) throws IOException, IllegalArgumentException { String user = SecurityUtils.getPrincipal(); logger.info("removeCredentials credentials for user {} ", user); - UserCredentials uc = credentials.removeUserCredentials(user); + UserCredentials uc = credentials().removeUserCredentials(user); if (uc == null) { return new JsonResponse(Status.NOT_FOUND).build(); } @@ -129,9 +127,14 @@ public Response removeCredentialEntity(@PathParam("entity") String entity) throw IOException, IllegalArgumentException { String user = SecurityUtils.getPrincipal(); logger.info("removeCredentialEntity for user {} entity {}", user, entity); - if (credentials.removeCredentialEntity(user, entity) == false) { + if (credentials().removeCredentialEntity(user, entity) == false) { return new JsonResponse(Status.NOT_FOUND).build(); } return new JsonResponse(Status.OK).build(); } + + private Credentials credentials() { + return ZeppelinSessions.credentials(SecurityUtils.getPrincipal()); + } + } diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java index 062f5b93978..f440a0a440d 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/HeliumRestApi.java @@ -25,6 +25,8 @@ import org.apache.zeppelin.notebook.Notebook; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.server.JsonResponse; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.utils.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,22 +41,11 @@ public class HeliumRestApi { Logger logger = LoggerFactory.getLogger(HeliumRestApi.class); - private Helium helium; - private HeliumApplicationFactory applicationFactory; - private Notebook notebook; private Gson gson = new Gson(); public HeliumRestApi() { } - public HeliumRestApi(Helium helium, - HeliumApplicationFactory heliumApplicationFactory, - Notebook notebook) { - this.helium = helium; - this.applicationFactory = heliumApplicationFactory; - this.notebook = notebook; - } - /** * Get all packages * @return @@ -62,14 +53,14 @@ public HeliumRestApi(Helium helium, @GET @Path("all") public Response getAll() { - return new JsonResponse(Response.Status.OK, "", helium.getAllPackageInfo()).build(); + return new JsonResponse(Response.Status.OK, "", helium().getAllPackageInfo()).build(); } @GET @Path("suggest/{noteId}/{paragraphId}") public Response suggest(@PathParam("noteId") String noteId, @PathParam("paragraphId") String paragraphId) { - Note note = notebook.getNote(noteId); + Note note = notebook().getNote(noteId); if (note == null) { return new JsonResponse(Response.Status.NOT_FOUND, "Note " + noteId + " not found").build(); } @@ -80,7 +71,7 @@ public Response suggest(@PathParam("noteId") String noteId, .build(); } - return new JsonResponse(Response.Status.OK, "", helium.suggestApp(paragraph)).build(); + return new JsonResponse(Response.Status.OK, "", helium().suggestApp(paragraph)).build(); } @POST @@ -89,7 +80,7 @@ public Response suggest(@PathParam("noteId") String noteId, @PathParam("paragraphId") String paragraphId, String heliumPackage) { - Note note = notebook.getNote(noteId); + Note note = notebook().getNote(noteId); if (note == null) { return new JsonResponse(Response.Status.NOT_FOUND, "Note " + noteId + " not found").build(); } @@ -101,8 +92,20 @@ public Response suggest(@PathParam("noteId") String noteId, } HeliumPackage pkg = gson.fromJson(heliumPackage, HeliumPackage.class); - String appId = applicationFactory.loadAndRun(pkg, paragraph); + String appId = heliumApplicationFactory().loadAndRun(pkg, paragraph); return new JsonResponse(Response.Status.OK, "", appId).build(); } + private Notebook notebook() { + return ZeppelinSessions.notebook(SecurityUtils.getPrincipal()); + } + + private Helium helium() { + return ZeppelinSessions.helium(SecurityUtils.getPrincipal()); + } + + private HeliumApplicationFactory heliumApplicationFactory() { + return ZeppelinSessions.heliumApplicationFactory(SecurityUtils.getPrincipal()); + } + } diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java index 6025b52c7f1..dde39268df7 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java @@ -33,9 +33,10 @@ import com.google.gson.Gson; import org.apache.commons.lang.exception.ExceptionUtils; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.utils.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonatype.aether.RepositoryException; import org.sonatype.aether.repository.RemoteRepository; import org.apache.zeppelin.annotation.ZeppelinApi; @@ -55,17 +56,11 @@ public class InterpreterRestApi { private static final Logger logger = LoggerFactory.getLogger(InterpreterRestApi.class); - private InterpreterFactory interpreterFactory; - Gson gson = new Gson(); public InterpreterRestApi() { } - public InterpreterRestApi(InterpreterFactory interpreterFactory) { - this.interpreterFactory = interpreterFactory; - } - /** * List all interpreter settings */ @@ -74,7 +69,7 @@ public InterpreterRestApi(InterpreterFactory interpreterFactory) { @ZeppelinApi public Response listSettings() { List interpreterSettings; - interpreterSettings = interpreterFactory.get(); + interpreterSettings = interpreterFactory().get(); return new JsonResponse<>(Status.OK, "", interpreterSettings).build(); } @@ -95,7 +90,7 @@ public Response newSettings(String message) { } Properties p = new Properties(); p.putAll(request.getProperties()); - InterpreterSetting interpreterSetting = interpreterFactory + InterpreterSetting interpreterSetting = interpreterFactory() .createNewSetting(request.getName(), request.getGroup(), request.getDependencies(), request.getOption(), p); logger.info("new setting created with {}", interpreterSetting.getId()); @@ -116,7 +111,7 @@ public Response updateSetting(String message, @PathParam("settingId") String set try { UpdateInterpreterSettingRequest request = gson.fromJson(message, UpdateInterpreterSettingRequest.class); - interpreterFactory + interpreterFactory() .setPropertyAndRestart(settingId, request.getOption(), request.getProperties(), request.getDependencies()); } catch (InterpreterException e) { @@ -128,7 +123,7 @@ public Response updateSetting(String message, @PathParam("settingId") String set return new JsonResponse<>(Status.INTERNAL_SERVER_ERROR, e.getMessage(), ExceptionUtils.getStackTrace(e)).build(); } - InterpreterSetting setting = interpreterFactory.get(settingId); + InterpreterSetting setting = interpreterFactory().get(settingId); if (setting == null) { return new JsonResponse<>(Status.NOT_FOUND, "", settingId).build(); } @@ -143,7 +138,7 @@ public Response updateSetting(String message, @PathParam("settingId") String set @ZeppelinApi public Response removeSetting(@PathParam("settingId") String settingId) throws IOException { logger.info("Remove interpreterSetting {}", settingId); - interpreterFactory.remove(settingId); + interpreterFactory().remove(settingId); return new JsonResponse(Status.OK).build(); } @@ -156,13 +151,13 @@ public Response removeSetting(@PathParam("settingId") String settingId) throws I public Response restartSetting(@PathParam("settingId") String settingId) { logger.info("Restart interpreterSetting {}", settingId); try { - interpreterFactory.restart(settingId); + interpreterFactory().restart(settingId); } catch (InterpreterException e) { logger.error("Exception in InterpreterRestApi while restartSetting ", e); return new JsonResponse<>(Status.NOT_FOUND, e.getMessage(), ExceptionUtils.getStackTrace(e)) .build(); } - InterpreterSetting setting = interpreterFactory.get(settingId); + InterpreterSetting setting = interpreterFactory().get(settingId); if (setting == null) { return new JsonResponse<>(Status.NOT_FOUND, "", settingId).build(); } @@ -175,7 +170,7 @@ public Response restartSetting(@PathParam("settingId") String settingId) { @GET @ZeppelinApi public Response listInterpreter(String message) { - Map m = interpreterFactory.getAvailableInterpreterSettings(); + Map m = interpreterFactory().getAvailableInterpreterSettings(); return new JsonResponse<>(Status.OK, "", m).build(); } @@ -186,7 +181,7 @@ public Response listInterpreter(String message) { @Path("repository") @ZeppelinApi public Response listRepositories() { - List interpreterRepositories = interpreterFactory.getRepositories(); + List interpreterRepositories = interpreterFactory().getRepositories(); return new JsonResponse<>(Status.OK, "", interpreterRepositories).build(); } @@ -201,7 +196,7 @@ public Response listRepositories() { public Response addRepository(String message) { try { Repository request = gson.fromJson(message, Repository.class); - interpreterFactory.addRepository(request.getId(), request.getUrl(), request.isSnapshot(), + interpreterFactory().addRepository(request.getId(), request.getUrl(), request.isSnapshot(), request.getAuthentication()); logger.info("New repository {} added", request.getId()); } catch (Exception e) { @@ -223,7 +218,7 @@ public Response addRepository(String message) { public Response removeRepository(@PathParam("repoId") String repoId) { logger.info("Remove repository {}", repoId); try { - interpreterFactory.removeRepository(repoId); + interpreterFactory().removeRepository(repoId); } catch (Exception e) { logger.error("Exception in InterpreterRestApi while removing repository ", e); return new JsonResponse<>(Status.INTERNAL_SERVER_ERROR, e.getMessage(), @@ -231,4 +226,9 @@ public Response removeRepository(@PathParam("repoId") String repoId) { } return new JsonResponse(Status.OK).build(); } + + private InterpreterFactory interpreterFactory() { + return ZeppelinSessions.interpreterFactory(SecurityUtils.getPrincipal()); + } + } diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java index 0a239221ef2..77731f9d9b4 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java @@ -16,11 +16,16 @@ */ package org.apache.zeppelin.rest; -import org.apache.shiro.authc.*; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.IncorrectCredentialsException; +import org.apache.shiro.authc.LockedAccountException; +import org.apache.shiro.authc.UnknownAccountException; +import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.apache.zeppelin.annotation.ZeppelinApi; import org.apache.zeppelin.server.JsonResponse; import org.apache.zeppelin.ticket.TicketContainer; +import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.utils.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,8 +82,8 @@ public Response postLogin(@FormParam("userName") String userName, HashSet roles = SecurityUtils.getRoles(); String principal = SecurityUtils.getPrincipal(); String ticket; - if ("anonymous".equals(principal)) - ticket = "anonymous"; + if (AuthenticationInfo.ANONYMOUS.equals(principal)) + ticket = AuthenticationInfo.ANONYMOUS; else ticket = TicketContainer.instance.getTicket(principal); diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java index 727211292b2..ca5f69c1bdd 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java @@ -39,7 +39,9 @@ import com.google.gson.Gson; import org.apache.commons.lang3.StringUtils; import org.apache.zeppelin.interpreter.InterpreterResult; -import org.apache.zeppelin.scheduler.Job; +import org.apache.zeppelin.notebook.Notebook; +import org.apache.zeppelin.notebook.NotebookAuthorization; +import org.apache.zeppelin.session.ZeppelinSessions; import org.apache.zeppelin.utils.InterpreterBindingUtils; import org.quartz.CronExpression; import org.slf4j.Logger; @@ -47,8 +49,6 @@ import org.apache.zeppelin.annotation.ZeppelinApi; import org.apache.zeppelin.notebook.Note; -import org.apache.zeppelin.notebook.Notebook; -import org.apache.zeppelin.notebook.NotebookAuthorization; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.rest.message.CronRequest; import org.apache.zeppelin.types.InterpreterSettingsList; @@ -69,19 +69,15 @@ public class NotebookRestApi { private static final Logger LOG = LoggerFactory.getLogger(NotebookRestApi.class); Gson gson = new Gson(); - private Notebook notebook; private NotebookServer notebookServer; + private SearchService notebookIndex; - private NotebookAuthorization notebookAuthorization; public NotebookRestApi() { } - public NotebookRestApi(Notebook notebook, NotebookServer notebookServer, SearchService search) { - this.notebook = notebook; + public NotebookRestApi(NotebookServer notebookServer) { this.notebookServer = notebookServer; - this.notebookIndex = search; - this.notebookAuthorization = notebook.getNotebookAuthorization(); } /** @@ -92,9 +88,9 @@ public NotebookRestApi(Notebook notebook, NotebookServer notebookServer, SearchS @ZeppelinApi public Response getNotePermissions(@PathParam("noteId") String noteId) { HashMap> permissionsMap = new HashMap<>(); - permissionsMap.put("owners", notebookAuthorization.getOwners(noteId)); - permissionsMap.put("readers", notebookAuthorization.getReaders(noteId)); - permissionsMap.put("writers", notebookAuthorization.getWriters(noteId)); + permissionsMap.put("owners", notebookAuthorization().getOwners(noteId)); + permissionsMap.put("readers", notebookAuthorization().getReaders(noteId)); + permissionsMap.put("writers", notebookAuthorization().getWriters(noteId)); return new JsonResponse<>(Status.OK, "", permissionsMap).build(); } @@ -121,7 +117,7 @@ public Response putNotePermissions(@PathParam("noteId") String noteId, String re HashMap> permMap = gson.fromJson(req, new TypeToken>>() { }.getType()); - Note note = notebook.getNote(noteId); + Note note = notebook().getNote(noteId); String principal = SecurityUtils.getPrincipal(); HashSet roles = SecurityUtils.getRoles(); LOG.info("Set permissions {} {} {} {} {}", noteId, principal, permMap.get("owners"), @@ -130,9 +126,9 @@ public Response putNotePermissions(@PathParam("noteId") String noteId, String re HashSet userAndRoles = new HashSet<>(); userAndRoles.add(principal); userAndRoles.addAll(roles); - if (!notebookAuthorization.isOwner(noteId, userAndRoles)) { + if (!notebookAuthorization().isOwner(noteId, userAndRoles)) { return new JsonResponse<>(Status.FORBIDDEN, - ownerPermissionError(userAndRoles, notebookAuthorization.getOwners(noteId))).build(); + ownerPermissionError(userAndRoles, notebookAuthorization().getOwners(noteId))).build(); } HashSet readers = permMap.get("readers"); @@ -154,11 +150,11 @@ public Response putNotePermissions(@PathParam("noteId") String noteId, String re } } - notebookAuthorization.setReaders(noteId, readers); - notebookAuthorization.setWriters(noteId, writers); - notebookAuthorization.setOwners(noteId, owners); - LOG.debug("After set permissions {} {} {}", notebookAuthorization.getOwners(noteId), - notebookAuthorization.getReaders(noteId), notebookAuthorization.getWriters(noteId)); + notebookAuthorization().setReaders(noteId, readers); + notebookAuthorization().setWriters(noteId, writers); + notebookAuthorization().setOwners(noteId, owners); + LOG.debug("After set permissions {} {} {}", notebookAuthorization().getOwners(noteId), + notebookAuthorization().getReaders(noteId), notebookAuthorization().getWriters(noteId)); AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); note.persist(subject); notebookServer.broadcastNote(note); @@ -176,7 +172,7 @@ public Response putNotePermissions(@PathParam("noteId") String noteId, String re public Response bind(@PathParam("noteId") String noteId, String req) throws IOException { List settingIdList = gson.fromJson(req, new TypeToken>() { }.getType()); - notebook.bindInterpretersToNote(noteId, settingIdList); + notebook().bindInterpretersToNote(noteId, settingIdList); return new JsonResponse<>(Status.OK).build(); } @@ -188,7 +184,7 @@ public Response bind(@PathParam("noteId") String noteId, String req) throws IOEx @ZeppelinApi public Response bind(@PathParam("noteId") String noteId) { List settingList = - InterpreterBindingUtils.getInterpreterBindings(notebook, noteId); + InterpreterBindingUtils.getInterpreterBindings(notebook(), noteId); notebookServer.broadcastInterpreterBindings(noteId, settingList); return new JsonResponse<>(Status.OK, "", settingList).build(); } @@ -206,7 +202,7 @@ public Response getNotebookList() throws IOException { @Path("{notebookId}") @ZeppelinApi public Response getNotebook(@PathParam("notebookId") String notebookId) throws IOException { - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -225,7 +221,7 @@ public Response getNotebook(@PathParam("notebookId") String notebookId) throws I @Path("export/{id}") @ZeppelinApi public Response exportNoteBook(@PathParam("id") String noteId) throws IOException { - String exportJson = notebook.exportNote(noteId); + String exportJson = notebook().exportNote(noteId); return new JsonResponse<>(Status.OK, "", exportJson).build(); } @@ -241,7 +237,7 @@ public Response exportNoteBook(@PathParam("id") String noteId) throws IOExceptio @ZeppelinApi public Response importNotebook(String req) throws IOException { AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); - Note newNote = notebook.importNote(req, null, subject); + Note newNote = notebook().importNote(req, null, subject); return new JsonResponse<>(Status.CREATED, "", newNote.getId()).build(); } @@ -259,7 +255,7 @@ public Response createNote(String message) throws IOException { LOG.info("Create new notebook by JSON {}", message); NewNotebookRequest request = gson.fromJson(message, NewNotebookRequest.class); AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); - Note note = notebook.createNote(subject); + Note note = notebook().createNote(subject); List initialParagraphs = request.getParagraphs(); if (initialParagraphs != null) { for (NewParagraphRequest paragraphRequest : initialParagraphs) { @@ -295,9 +291,9 @@ public Response deleteNote(@PathParam("notebookId") String notebookId) throws IO LOG.info("Delete notebook {} ", notebookId); AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); if (!(notebookId.isEmpty())) { - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note != null) { - notebook.removeNote(notebookId, subject); + notebook().removeNote(notebookId, subject); } } @@ -324,7 +320,7 @@ public Response cloneNote(@PathParam("notebookId") String notebookId, String mes newNoteName = request.getName(); } AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); - Note newNote = notebook.cloneNote(notebookId, newNoteName, subject); + Note newNote = notebook().cloneNote(notebookId, newNoteName, subject); notebookServer.broadcastNote(newNote); notebookServer.broadcastNoteList(subject); return new JsonResponse<>(Status.CREATED, "", newNote.getId()).build(); @@ -344,7 +340,7 @@ public Response insertParagraph(@PathParam("notebookId") String notebookId, Stri throws IOException { LOG.info("insert paragraph {} {}", notebookId, message); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -381,7 +377,7 @@ public Response getParagraph(@PathParam("notebookId") String notebookId, @PathParam("paragraphId") String paragraphId) throws IOException { LOG.info("get paragraph {} {}", notebookId, paragraphId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse(Status.NOT_FOUND, "note not found.").build(); } @@ -409,7 +405,7 @@ public Response moveParagraph(@PathParam("notebookId") String notebookId, throws IOException { LOG.info("move paragraph {} {} {}", notebookId, paragraphId, newIndex); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse(Status.NOT_FOUND, "note not found.").build(); } @@ -446,7 +442,7 @@ public Response deleteParagraph(@PathParam("notebookId") String notebookId, @PathParam("paragraphId") String paragraphId) throws IOException { LOG.info("delete paragraph {} {}", notebookId, paragraphId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse(Status.NOT_FOUND, "note not found.").build(); } @@ -477,7 +473,7 @@ public Response deleteParagraph(@PathParam("notebookId") String notebookId, public Response runNoteJobs(@PathParam("notebookId") String notebookId) throws IOException, IllegalArgumentException { LOG.info("run notebook jobs {} ", notebookId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -506,7 +502,7 @@ public Response runNoteJobs(@PathParam("notebookId") String notebookId) public Response stopNoteJobs(@PathParam("notebookId") String notebookId) throws IOException, IllegalArgumentException { LOG.info("stop notebook jobs {} ", notebookId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -532,7 +528,7 @@ public Response stopNoteJobs(@PathParam("notebookId") String notebookId) public Response getNoteJobStatus(@PathParam("notebookId") String notebookId) throws IOException, IllegalArgumentException { LOG.info("get notebook job status."); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -555,7 +551,7 @@ public Response getNoteParagraphJobStatus(@PathParam("notebookId") String notebo @PathParam("paragraphId") String paragraphId) throws IOException, IllegalArgumentException { LOG.info("get notebook paragraph job status."); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -585,7 +581,7 @@ public Response runParagraph(@PathParam("notebookId") String notebookId, throws IOException, IllegalArgumentException { LOG.info("run paragraph job asynchronously {} {} {}", notebookId, paragraphId, message); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -622,7 +618,7 @@ public Response runParagraphSynchronously(@PathParam("notebookId") String noteId IOException, IllegalArgumentException { LOG.info("run paragraph synchronously {} {} {}", noteId, paragraphId, message); - Note note = notebook.getNote(noteId); + Note note = notebook().getNote(noteId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -668,7 +664,7 @@ public Response stopParagraph(@PathParam("notebookId") String notebookId, * https://issues.apache.org/jira/browse/ZEPPELIN-1163 */ LOG.info("stop paragraph job {} ", notebookId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -698,7 +694,7 @@ public Response registerCronJob(@PathParam("notebookId") String notebookId, Stri CronRequest request = gson.fromJson(message, CronRequest.class); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -710,7 +706,7 @@ public Response registerCronJob(@PathParam("notebookId") String notebookId, Stri Map config = note.getConfig(); config.put("cron", request.getCronString()); note.setConfig(config); - notebook.refreshCron(note.getId()); + notebook().refreshCron(note.getId()); return new JsonResponse<>(Status.OK).build(); } @@ -730,7 +726,7 @@ public Response removeCronJob(@PathParam("notebookId") String notebookId) // TODO(jl): Fixed notebookId to noteId LOG.info("Remove cron job note {}", notebookId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -738,7 +734,7 @@ public Response removeCronJob(@PathParam("notebookId") String notebookId) Map config = note.getConfig(); config.put("cron", null); note.setConfig(config); - notebook.refreshCron(note.getId()); + notebook().refreshCron(note.getId()); return new JsonResponse<>(Status.OK).build(); } @@ -758,7 +754,7 @@ public Response getCronJob(@PathParam("notebookId") String notebookId) // TODO(jl): Fixed notebookId to noteId LOG.info("Get cron job note {}", notebookId); - Note note = notebook.getNote(notebookId); + Note note = notebook().getNote(notebookId); if (note == null) { return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build(); } @@ -779,7 +775,7 @@ public Response getJobListforNotebook() throws IOException, IllegalArgumentExcep LOG.info("Get notebook jobs for job manager"); AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); - List> notebookJobs = notebook + List> notebookJobs = notebook() .getJobListByUnixTime(false, 0, subject); Map response = new HashMap<>(); @@ -807,7 +803,7 @@ public Response getUpdatedJobListforNotebook( List> notebookJobs; AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal()); - notebookJobs = notebook.getJobListByUnixTime(false, lastUpdateUnixTime, subject); + notebookJobs = notebook().getJobListByUnixTime(false, lastUpdateUnixTime, subject); Map response = new HashMap<>(); response.put("lastResponseUnixTime", System.currentTimeMillis()); @@ -833,9 +829,9 @@ public Response search(@QueryParam("q") String queryTerm) { for (int i = 0; i < notebooksFound.size(); i++) { String[] Id = notebooksFound.get(i).get("id").split("/", 2); String noteId = Id[0]; - if (!notebookAuthorization.isOwner(noteId, userAndRoles) && - !notebookAuthorization.isReader(noteId, userAndRoles) && - !notebookAuthorization.isWriter(noteId, userAndRoles)) { + if (!notebookAuthorization().isOwner(noteId, userAndRoles) && + !notebookAuthorization().isReader(noteId, userAndRoles) && + !notebookAuthorization().isWriter(noteId, userAndRoles)) { notebooksFound.remove(i); i--; } @@ -844,13 +840,20 @@ public Response search(@QueryParam("q") String queryTerm) { return new JsonResponse<>(Status.OK, notebooksFound).build(); } + private Notebook notebook() { + return ZeppelinSessions.notebook(SecurityUtils.getPrincipal()); + } + + private NotebookAuthorization notebookAuthorization() { + return ZeppelinSessions.notebookAuthorization(SecurityUtils.getPrincipal()); + } private void handleParagraphParams(String message, Note note, Paragraph paragraph) throws IOException { // handle params if presented if (!StringUtils.isEmpty(message)) { RunParagraphWithParametersRequest request = - gson.fromJson(message, RunParagraphWithParametersRequest.class); + gson.fromJson(message, RunParagraphWithParametersRequest.class); Map paramsForUpdating = request.getParams(); if (paramsForUpdating != null) { paragraph.settings.getParams().putAll(paramsForUpdating); diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java index 7af52c8c8ba..4e43b5b3ca0 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/SecurityRestApi.java @@ -28,6 +28,7 @@ import org.apache.zeppelin.server.ActiveDirectoryGroupRealm; import org.apache.zeppelin.server.JsonResponse; import org.apache.zeppelin.ticket.TicketContainer; +import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.utils.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,8 +73,8 @@ public Response ticket() { JsonResponse response; // ticket set to anonymous for anonymous user. Simplify testing. String ticket; - if ("anonymous".equals(principal)) - ticket = "anonymous"; + if (AuthenticationInfo.ANONYMOUS.equals(principal)) + ticket = AuthenticationInfo.ANONYMOUS; else ticket = TicketContainer.instance.getTicket(principal); diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java index d352c080176..731aef8e472 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java @@ -43,7 +43,9 @@ import org.apache.zeppelin.scheduler.SchedulerFactory; import org.apache.zeppelin.search.LuceneSearch; import org.apache.zeppelin.search.SearchService; +import org.apache.zeppelin.session.ZeppelinSessionListener; import org.apache.zeppelin.socket.NotebookServer; +import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.user.Credentials; import org.apache.zeppelin.utils.SecurityUtils; import org.eclipse.jetty.http.HttpVersion; @@ -65,51 +67,18 @@ public class ZeppelinServer extends Application { private static final Logger LOG = LoggerFactory.getLogger(ZeppelinServer.class); - public static Notebook notebook; public static Server jettyWebServer; public static NotebookServer notebookWsServer; - public static Helium helium; - public static HeliumApplicationFactory heliumApplicationFactory; - private SchedulerFactory schedulerFactory; - private InterpreterFactory replFactory; - private NotebookRepo notebookRepo; - private SearchService notebookIndex; - private NotebookAuthorization notebookAuthorization; - private Credentials credentials; - private DependencyResolver depResolver; + public static ZeppelinConfiguration conf; public ZeppelinServer() throws Exception { - ZeppelinConfiguration conf = ZeppelinConfiguration.create(); - - this.depResolver = new DependencyResolver( - conf.getString(ConfVars.ZEPPELIN_INTERPRETER_LOCALREPO)); - - this.helium = new Helium(conf.getHeliumConfPath(), conf.getHeliumDefaultLocalRegistryPath()); - this.heliumApplicationFactory = new HeliumApplicationFactory(); - this.schedulerFactory = new SchedulerFactory(); - this.replFactory = new InterpreterFactory(conf, notebookWsServer, - notebookWsServer, heliumApplicationFactory, depResolver); - this.notebookRepo = new NotebookRepoSync(conf); - this.notebookIndex = new LuceneSearch(); - this.notebookAuthorization = new NotebookAuthorization(conf); - this.credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath()); - notebook = new Notebook(conf, - notebookRepo, schedulerFactory, replFactory, notebookWsServer, - notebookIndex, notebookAuthorization, credentials); - - // to update notebook from application event from remote process. - heliumApplicationFactory.setNotebook(notebook); - // to update fire websocket event on application event. - heliumApplicationFactory.setApplicationEventListener(notebookWsServer); - - notebook.addNotebookEventListener(heliumApplicationFactory); - notebook.addNotebookEventListener(notebookWsServer.getNotebookInformationListener()); + } public static void main(String[] args) throws InterruptedException { - ZeppelinConfiguration conf = ZeppelinConfiguration.create(); + conf = ZeppelinConfiguration.create(); conf.setProperty("args", args); jettyWebServer = setupJettyServer(conf); @@ -126,6 +95,8 @@ public static void main(String[] args) throws InterruptedException { // Notebook server setupNotebookServer(webApp, conf); + webApp.addEventListener(new ZeppelinSessionListener()); + //Below is commented since zeppelin-docs module is removed. //final WebAppContext webAppSwagg = setupWebAppSwagger(conf); @@ -143,8 +114,9 @@ public static void main(String[] args) throws InterruptedException { LOG.info("Shutting down Zeppelin Server ... "); try { jettyWebServer.stop(); - notebook.getInterpreterFactory().close(); - notebook.close(); +// TODO(ECH) +// notebook.getInterpreterFactory().close(); +// notebook.close(); } catch (Exception e) { LOG.error("Error while stopping servlet container", e); } @@ -165,7 +137,8 @@ public static void main(String[] args) throws InterruptedException { } jettyWebServer.join(); - ZeppelinServer.notebook.getInterpreterFactory().close(); +// TODO(ECH) +// ZeppelinServer.notebook.getInterpreterFactory().close(); } private static Server setupJettyServer(ZeppelinConfiguration conf) { @@ -309,16 +282,16 @@ public Set getSingletons() { ZeppelinRestApi root = new ZeppelinRestApi(); singletons.add(root); - NotebookRestApi notebookApi = new NotebookRestApi(notebook, notebookWsServer, notebookIndex); + NotebookRestApi notebookApi = new NotebookRestApi(notebookWsServer); singletons.add(notebookApi); - HeliumRestApi heliumApi = new HeliumRestApi(helium, heliumApplicationFactory, notebook); + HeliumRestApi heliumApi = new HeliumRestApi(); singletons.add(heliumApi); - InterpreterRestApi interpreterApi = new InterpreterRestApi(replFactory); + InterpreterRestApi interpreterApi = new InterpreterRestApi(); singletons.add(interpreterApi); - CredentialRestApi credentialApi = new CredentialRestApi(credentials); + CredentialRestApi credentialApi = new CredentialRestApi(); singletons.add(credentialApi); SecurityRestApi securityApi = new SecurityRestApi(); @@ -327,7 +300,7 @@ public Set getSingletons() { LoginRestApi loginRestApi = new LoginRestApi(); singletons.add(loginRestApi); - ConfigurationsRestApi settingsApi = new ConfigurationsRestApi(notebook); + ConfigurationsRestApi settingsApi = new ConfigurationsRestApi(); singletons.add(settingsApi); return singletons; diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/session/ZeppelinSessionListener.java b/zeppelin-server/src/main/java/org/apache/zeppelin/session/ZeppelinSessionListener.java new file mode 100644 index 00000000000..950612fbba5 --- /dev/null +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/session/ZeppelinSessionListener.java @@ -0,0 +1,49 @@ +/* + * 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.session; + +import org.apache.zeppelin.user.AuthenticationInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +/** + *HTTP users listener. + */ +public class ZeppelinSessionListener implements HttpSessionListener { + private static final Logger LOGGER = LoggerFactory.getLogger(ZeppelinSessionListener.class); + + @Override + public void sessionCreated(HttpSessionEvent httpSessionEvent) { + LOGGER.info("Session Created: " + httpSessionEvent.getSession().getId()); + } + + @Override + public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { + AuthenticationInfo authenticationInfo = + (AuthenticationInfo) httpSessionEvent.getSession() + .getAttribute(ZeppelinSessions.ZEPPELIN_AUTH_USER_KEY); + if (authenticationInfo != null) { + ZeppelinSessions.components.remove(authenticationInfo.getUser()); + LOGGER.info("Session ID=" + httpSessionEvent.getSession().getId() + + " destroyed for authenticationInfo=" + authenticationInfo.getUser()); + } + } + +} diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/session/ZeppelinSessions.java b/zeppelin-server/src/main/java/org/apache/zeppelin/session/ZeppelinSessions.java new file mode 100644 index 00000000000..1e3c04ea01a --- /dev/null +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/session/ZeppelinSessions.java @@ -0,0 +1,157 @@ +/* + * 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.session; + +import org.apache.zeppelin.conf.ZeppelinConfiguration; +import org.apache.zeppelin.dep.DependencyResolver; +import org.apache.zeppelin.helium.Helium; +import org.apache.zeppelin.helium.HeliumApplicationFactory; +import org.apache.zeppelin.interpreter.InterpreterFactory; +import org.apache.zeppelin.notebook.Notebook; +import org.apache.zeppelin.notebook.NotebookAuthorization; +import org.apache.zeppelin.notebook.repo.NotebookRepo; +import org.apache.zeppelin.notebook.repo.NotebookRepoSync; +import org.apache.zeppelin.scheduler.SchedulerFactory; +import org.apache.zeppelin.search.LuceneSearch; +import org.apache.zeppelin.search.SearchService; +import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.user.AuthenticationInfo; +import org.apache.zeppelin.user.Credentials; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + * Maintain HTTP user session states. + */ +public class ZeppelinSessions { + private static final Logger LOGGER = LoggerFactory.getLogger(ZeppelinSessions.class); + + public static final String ZEPPELIN_AUTH_USER_KEY = "_authUser"; + public static final String INTERPRETER_SHARED_FACTORIES_KEY = "_sharedFactories"; + + private static final ZeppelinConfiguration conf = ZeppelinServer.conf; + private static NotebookAuthorization notebookAuthorization = new NotebookAuthorization(conf, null); + + public static Map components = new HashMap(); + + public static Notebook notebook(String principal) { + return component(principal).notebook; + } + + public static Credentials credentials(String principal) { + return component(principal).credentials; + } + + public static NotebookAuthorization notebookAuthorization(String principal) { + return component(principal).notebookAuthorization; + } + + public static Helium helium(String principal) { + return component(principal).helium; + } + + public static HeliumApplicationFactory heliumApplicationFactory(String principal) { + return component(principal).heliumApplicationFactory; + } + + public static InterpreterFactory interpreterFactory(String principal) { + return component(principal).interpreterFactory; + } + + private static Component component(String principal) { + + String componentKey = conf.isInterpreterPeruserFactories() ? + principal : + INTERPRETER_SHARED_FACTORIES_KEY; + + Component component = components.get(componentKey); + + if (component == null) { + + try { + + AuthenticationInfo authenticationInfo = new AuthenticationInfo(principal); + + component = new Component(); + + component.depResolver = new DependencyResolver( + conf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETER_LOCALREPO)); + + component.helium = new Helium(conf.getHeliumConfPath(), + conf.getHeliumDefaultLocalRegistryPath()); + component.heliumApplicationFactory = new HeliumApplicationFactory(); + component.schedulerFactory = new SchedulerFactory(); + + component.interpreterFactory = new InterpreterFactory(conf, + ZeppelinServer.notebookWsServer, + ZeppelinServer.notebookWsServer, component.heliumApplicationFactory, + component.depResolver, authenticationInfo); + + component.notebookRepo = new NotebookRepoSync(conf, authenticationInfo); + component.searchService = new LuceneSearch(); + component.notebookAuthorization = notebookAuthorization; + component.credentials = new Credentials( + conf.credentialsPersist(), conf.getCredentialsPath()); + + component.notebook = new Notebook(conf, + component.notebookRepo, component.schedulerFactory, + component.interpreterFactory, ZeppelinServer.notebookWsServer, + component.searchService, component.notebookAuthorization, component.credentials); + + // to update notebook from application event from remote process. + component.heliumApplicationFactory.setNotebook(component.notebook); + + // to update fire websocket event on application event. + component.heliumApplicationFactory + .setApplicationEventListener(ZeppelinServer.notebookWsServer); + + component.notebook.addNotebookEventListener(component.heliumApplicationFactory); + + components.put(componentKey, component); + + } + catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + + } + + return component; + + } + + /** + * Container for Zeppelin server components. + */ + public static class Component { + public SchedulerFactory schedulerFactory; + public InterpreterFactory interpreterFactory; + public NotebookRepo notebookRepo; + public SearchService searchService; + public NotebookAuthorization notebookAuthorization; + public Credentials credentials; + public DependencyResolver depResolver; + public Helium helium; + public HeliumApplicationFactory heliumApplicationFactory; + public Notebook notebook; + } + +} 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 e3328024818..4ac94395eea 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 @@ -43,6 +43,7 @@ import org.apache.zeppelin.scheduler.Job; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; import org.apache.zeppelin.ticket.TicketContainer; import org.apache.zeppelin.types.InterpreterSettingsList; import org.apache.zeppelin.user.AuthenticationInfo; @@ -86,8 +87,8 @@ String getKey() { final Map> noteSocketMap = new HashMap<>(); final Queue connectedSockets = new ConcurrentLinkedQueue<>(); - private Notebook notebook() { - return ZeppelinServer.notebook; + private Notebook notebook(String principal) { + return ZeppelinSessions.notebook(principal); } @Override @@ -119,7 +120,6 @@ public void onOpen(NotebookSocket conn) { @Override public void onMessage(NotebookSocket conn, String msg) { - Notebook notebook = notebook(); try { Message messagereceived = deserializeMessage(msg); LOG.debug("RECEIVE << " + messagereceived.op); @@ -147,7 +147,7 @@ public void onMessage(NotebookSocket conn, String msg) { ZeppelinConfiguration conf = ZeppelinConfiguration.create(); boolean allowAnonymous = conf. getBoolean(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED); - if (!allowAnonymous && messagereceived.principal.equals("anonymous")) { + if (!allowAnonymous && messagereceived.principal.equals(AuthenticationInfo.ANONYMOUS)) { throw new Exception("Anonymous access not allowed "); } @@ -162,6 +162,8 @@ public void onMessage(NotebookSocket conn, String msg) { } AuthenticationInfo subject = new AuthenticationInfo(messagereceived.principal); + Notebook notebook = notebook(messagereceived.runAs); + /** Lets be elegant here */ switch (messagereceived.op) { case LIST_NOTES: @@ -330,7 +332,7 @@ private String getOpenNoteId(NotebookSocket socket) { private void broadcastToNoteBindedInterpreter(String interpreterGroupId, Message m) { - Notebook notebook = notebook(); + Notebook notebook = notebook(m.principal ); List notes = notebook.getAllNotes(); for (Note note : notes) { List ids = notebook.getInterpreterFactory().getInterpreters(note.getId()); @@ -400,8 +402,10 @@ private void unicast(Message m, NotebookSocket conn) { public void unicastNotebookJobInfo(NotebookSocket conn, Message fromMessage) throws IOException { addConnectionToNote(JOB_MANAGER_SERVICE.JOB_MANAGER_PAGE.getKey(), conn); AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal); - List> notebookJobs = notebook() - .getJobListByUnixTime(false, 0, subject); + + List> notebookJobs = notebook( + fromMessage.principal).getJobListByUnixTime(false, 0, subject); + Map response = new HashMap<>(); response.put("lastResponseUnixTime", System.currentTimeMillis()); @@ -411,12 +415,12 @@ public void unicastNotebookJobInfo(NotebookSocket conn, Message fromMessage) thr .put("notebookJobs", response))); } - public void broadcastUpdateNotebookJobInfo(long lastUpdateUnixTime) throws IOException { + public void broadcastUpdateNotebookJobInfo(long lastUpdateUnixTime, String user) throws IOException { List> notebookJobs = new LinkedList<>(); - Notebook notebookObject = notebook(); + Notebook notebookObject = notebook(user); List> jobNotes = null; if (notebookObject != null) { - jobNotes = notebook().getJobListByUnixTime(false, lastUpdateUnixTime, null); + jobNotes = notebook(user).getJobListByUnixTime(false, lastUpdateUnixTime, null); notebookJobs = jobNotes == null ? notebookJobs : jobNotes; } @@ -438,9 +442,9 @@ public void saveInterpreterBindings(NotebookSocket conn, Message fromMessage) { List settingIdList = gson.fromJson(String.valueOf( fromMessage.data.get("selectedSettingIds")), new TypeToken>() { }.getType()); - notebook().bindInterpretersToNote(noteId, settingIdList); + notebook(fromMessage.principal).bindInterpretersToNote(noteId, settingIdList); broadcastInterpreterBindings(noteId, - InterpreterBindingUtils.getInterpreterBindings(notebook(), noteId)); + InterpreterBindingUtils.getInterpreterBindings(notebook(fromMessage.principal), noteId)); } catch (Exception e) { LOG.error("Error while saving interpreter bindings", e); } @@ -450,7 +454,7 @@ public void getInterpreterBindings(NotebookSocket conn, Message fromMessage) throws IOException { String noteID = (String) fromMessage.data.get("noteID"); List settingList = - InterpreterBindingUtils.getInterpreterBindings(notebook(), noteID); + InterpreterBindingUtils.getInterpreterBindings(notebook(fromMessage.principal), noteID); conn.send(serializeMessage(new Message(OP.INTERPRETER_BINDINGS) .put("interpreterBindings", settingList))); } @@ -458,7 +462,7 @@ public void getInterpreterBindings(NotebookSocket conn, Message fromMessage) public List> generateNotebooksInfo(boolean needsReload, AuthenticationInfo subject) { - Notebook notebook = notebook(); + Notebook notebook = notebook(subject.getUser()); ZeppelinConfiguration conf = notebook.getConf(); String homescreenNotebookId = conf.getString(ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN); @@ -1119,7 +1123,7 @@ private void runParagraph(NotebookSocket conn, HashSet userAndRoles, Not String text = (String) fromMessage.get("paragraph"); p.setText(text); p.setTitle((String) fromMessage.get("title")); - if (!fromMessage.principal.equals("anonymous")) { + if (!fromMessage.principal.equals(AuthenticationInfo.ANONYMOUS)) { AuthenticationInfo authenticationInfo = new AuthenticationInfo(fromMessage.principal, fromMessage.ticket); p.setAuthenticationInfo(authenticationInfo); @@ -1309,7 +1313,7 @@ public NotebookInformationListener(NotebookServer notebookServer) { @Override public void onParagraphRemove(Paragraph p) { try { - notebookServer.broadcastUpdateNotebookJobInfo(System.currentTimeMillis() - 5000); + notebookServer.broadcastUpdateNotebookJobInfo(System.currentTimeMillis() - 5000, p.getAuthenticationInfo().getUser()); } catch (IOException ioe) { LOG.error("can not broadcast for job manager {}", ioe.getMessage()); } @@ -1318,7 +1322,8 @@ public void onParagraphRemove(Paragraph p) { @Override public void onNoteRemove(Note note) { try { - notebookServer.broadcastUpdateNotebookJobInfo(System.currentTimeMillis() - 5000); + notebookServer.broadcastUpdateNotebookJobInfo(System.currentTimeMillis() - 5000, + SecurityUtils.getPrincipal()); } catch (IOException ioe) { LOG.error("can not broadcast for job manager {}", ioe.getMessage()); } @@ -1347,7 +1352,7 @@ public void onNoteRemove(Note note) { @Override public void onParagraphCreate(Paragraph p) { - Notebook notebook = notebookServer.notebook(); + Notebook notebook = notebookServer.notebook(p.getAuthenticationInfo().getUser()); List> notebookJobs = notebook.getJobListByParagraphId( p.getId() ); @@ -1361,7 +1366,7 @@ public void onParagraphCreate(Paragraph p) { @Override public void onNoteCreate(Note note) { - Notebook notebook = notebookServer.notebook(); + Notebook notebook = notebookServer.notebook(SecurityUtils.getPrincipal()); List> notebookJobs = notebook.getJobListBymNotebookId( note.getId() ); @@ -1375,7 +1380,7 @@ public void onNoteCreate(Note note) { @Override public void onParagraphStatusChange(Paragraph p, Status status) { - Notebook notebook = notebookServer.notebook(); + Notebook notebook = notebookServer.notebook(p.getAuthenticationInfo().getUser()); List> notebookJobs = notebook.getJobListByParagraphId( p.getId() ); @@ -1390,7 +1395,7 @@ public void onParagraphStatusChange(Paragraph p, Status status) { @Override public void onUnbindInterpreter(Note note, InterpreterSetting setting) { - Notebook notebook = notebookServer.notebook(); + Notebook notebook = notebookServer.notebook(SecurityUtils.getPrincipal()); List> notebookJobs = notebook.getJobListBymNotebookId( note.getId() ); @@ -1448,7 +1453,10 @@ public void afterStatusChange(Job job, Status before, Status after) { notebookServer.broadcastNote(note); try { - notebookServer.broadcastUpdateNotebookJobInfo(System.currentTimeMillis() - 5000); + System.out.println(SecurityUtils.getPrincipal()); + + notebookServer.broadcastUpdateNotebookJobInfo(System.currentTimeMillis() - 5000, + SecurityUtils.getPrincipal()); } catch (IOException e) { LOG.error("can not broadcast for job manager {}", e); } @@ -1498,7 +1506,8 @@ public NotebookEventListener getNotebookInformationListener() { private void sendAllAngularObjects(Note note, NotebookSocket conn) throws IOException { List settings = - notebook().getInterpreterFactory().getInterpreterSettings(note.getId()); + notebook(SecurityUtils.getPrincipal()).getInterpreterFactory() + .getInterpreterSettings(note.getId()); if (settings == null || settings.size() == 0) { return; } @@ -1526,7 +1535,7 @@ public void onAdd(String interpreterGroupId, AngularObject object) { @Override public void onUpdate(String interpreterGroupId, AngularObject object) { - Notebook notebook = notebook(); + Notebook notebook = notebook(SecurityUtils.getPrincipal()); if (notebook == null) { return; } @@ -1555,7 +1564,7 @@ public void onUpdate(String interpreterGroupId, AngularObject object) { @Override public void onRemove(String interpreterGroupId, String name, String noteId, String paragraphId) { - Notebook notebook = notebook(); + Notebook notebook = notebook(SecurityUtils.getPrincipal()); List notes = notebook.getAllNotes(); for (Note note : notes) { if (noteId != null && !note.getId().equals(noteId)) { diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/ticket/TicketContainer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/ticket/TicketContainer.java index 513bb4a9337..3bc256dbac0 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/ticket/TicketContainer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/ticket/TicketContainer.java @@ -17,6 +17,8 @@ package org.apache.zeppelin.ticket; +import org.apache.zeppelin.user.AuthenticationInfo; + import java.util.Calendar; import java.util.Map; import java.util.UUID; @@ -52,7 +54,8 @@ private static class Entry { * @return true if ticket assigned to principal. */ public boolean isValid(String principal, String ticket) { - if ("anonymous".equals(principal) && "anonymous".equals(ticket)) + if (AuthenticationInfo.ANONYMOUS.equals(principal) + && AuthenticationInfo.ANONYMOUS.equals(ticket)) return true; Entry entry = sessions.get(principal); return entry != null && entry.ticket.equals(ticket); @@ -60,7 +63,7 @@ public boolean isValid(String principal, String ticket) { /** * get or create ticket for Websocket authentication assigned to authenticated shiro user - * For unathenticated user (anonymous), always return ticket value "anonymous" + * For unathenticated user (anonymous), always return ticket value AuthenticationInfo.ANONYMOUS * @param principal * @return */ @@ -68,8 +71,8 @@ public synchronized String getTicket(String principal) { Entry entry = sessions.get(principal); String ticket; if (entry == null) { - if (principal.equals("anonymous")) - ticket = "anonymous"; + if (principal.equals(AuthenticationInfo.ANONYMOUS)) + ticket = AuthenticationInfo.ANONYMOUS; else ticket = UUID.randomUUID().toString(); } else { diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java index f9e5929a882..f70f00a5e59 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java @@ -24,6 +24,7 @@ import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.zeppelin.conf.ZeppelinConfiguration; +import org.apache.zeppelin.user.AuthenticationInfo; import java.net.InetAddress; import java.net.URI; @@ -60,7 +61,7 @@ public static Boolean isValidOrigin(String sourceHost, ZeppelinConfiguration con } /** - * Return the authenticated user if any otherwise returns "anonymous" + * Return the authenticated user if any otherwise returns AuthenticationInfo.ANONYMOUS * * @return shiro principal */ @@ -71,7 +72,7 @@ public static String getPrincipal() { if (subject.isAuthenticated()) { principal = subject.getPrincipal().toString(); } else { - principal = "anonymous"; + principal = AuthenticationInfo.ANONYMOUS; } return principal; } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java index 580e5a08e94..47c03a8111c 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java @@ -40,6 +40,8 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.interpreter.InterpreterSetting; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.user.AuthenticationInfo; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; @@ -145,7 +147,7 @@ protected static void startUp() throws Exception { if ("true".equals(System.getenv("CI"))) { // assume first one is spark InterpreterSetting sparkIntpSetting = null; - for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) { + for(InterpreterSetting intpSetting : ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().get()) { if (intpSetting.getName().equals("spark")) { sparkIntpSetting = intpSetting; } @@ -159,11 +161,11 @@ protected static void startUp() throws Exception { sparkIntpSetting.getProperties().setProperty("spark.home", getSparkHome()); pySpark = true; sparkR = true; - ZeppelinServer.notebook.getInterpreterFactory().restart(sparkIntpSetting.getId()); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().restart(sparkIntpSetting.getId()); } else { // assume first one is spark InterpreterSetting sparkIntpSetting = null; - for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) { + for(InterpreterSetting intpSetting : ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().get()) { if (intpSetting.getName().equals("spark")) { sparkIntpSetting = intpSetting; } @@ -179,7 +181,7 @@ protected static void startUp() throws Exception { sparkR = true; } - ZeppelinServer.notebook.getInterpreterFactory().restart(sparkIntpSetting.getId()); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().restart(sparkIntpSetting.getId()); } } } @@ -240,10 +242,10 @@ private static boolean isActiveSparkHome(File dir) { protected static void shutDown() throws Exception { if (!wasRunning) { // restart interpreter to stop all interpreter processes - List settingList = ZeppelinServer.notebook.getInterpreterFactory() + List settingList = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory() .getDefaultInterpreterSettingList(); for (String setting : settingList) { - ZeppelinServer.notebook.getInterpreterFactory().restart(setting); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().restart(setting); } LOG.info("Terminating test Zeppelin..."); diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java index c767eb05786..9f989042d73 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java @@ -30,6 +30,8 @@ import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.FixMethodOrder; @@ -68,7 +70,7 @@ public void getAvailableInterpreters() throws IOException { Map resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken>() { }.getType()); Map body = (Map) resp.get("body"); - assertEquals(ZeppelinServer.notebook.getInterpreterFactory().getAvailableInterpreterSettings().size(), body.size()); + assertEquals(ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().getAvailableInterpreterSettings().size(), body.size()); get.releaseConnection(); } @@ -131,7 +133,7 @@ public void testSettingsCreateWithEmptyJson() throws IOException { @Test public void testInterpreterAutoBinding() throws IOException { // create note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); // check interpreter is binded GetMethod get = httpGet("/notebook/interpreter/bind/" + note.getId()); @@ -144,13 +146,13 @@ public void testInterpreterAutoBinding() throws IOException { get.releaseConnection(); //cleanup - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testInterpreterRestart() throws IOException, InterruptedException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); note.addParagraph(); Paragraph p = note.getLastParagraph(); Map config = p.getConfig(); @@ -167,7 +169,7 @@ public void testInterpreterRestart() throws IOException, InterruptedException { // restart interpreter - for (InterpreterSetting setting : ZeppelinServer.notebook.getInterpreterFactory().getInterpreterSettings(note.getId())) { + for (InterpreterSetting setting : ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().getInterpreterSettings(note.getId())) { if (setting.getName().equals("md")) { // Call Restart Interpreter REST API PutMethod put = httpPut("/interpreter/setting/restart/" + setting.getId(), ""); @@ -187,7 +189,7 @@ public void testInterpreterRestart() throws IOException, InterruptedException { } assertEquals("

markdown restarted

\n", p.getResult().message()); //cleanup - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java index d7f55f54744..a28f0db9094 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java @@ -28,6 +28,8 @@ import org.apache.zeppelin.notebook.NotebookAuthorization; import org.apache.zeppelin.notebook.NotebookAuthorizationInfoSaving; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.FixMethodOrder; @@ -62,7 +64,7 @@ public static void destroy() throws Exception { @Test public void testPermissions() throws IOException { - Note note1 = ZeppelinServer.notebook.createNote(null); + Note note1 = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); // Set only readers String jsonRequest = "{\"readers\":[\"admin-team\"],\"owners\":[]," + "\"writers\":[]}"; @@ -80,12 +82,12 @@ public void testPermissions() throws IOException { // Check that both owners and writers is set to the princpal if empty assertEquals(authInfo.get("readers"), Lists.newArrayList("admin-team")); - assertEquals(authInfo.get("owners"), Lists.newArrayList("anonymous")); - assertEquals(authInfo.get("writers"), Lists.newArrayList("anonymous")); + assertEquals(authInfo.get("owners"), Lists.newArrayList(AuthenticationInfo.ANONYMOUS)); + assertEquals(authInfo.get("writers"), Lists.newArrayList(AuthenticationInfo.ANONYMOUS)); get.releaseConnection(); - Note note2 = ZeppelinServer.notebook.createNote(null); + Note note2 = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); // Set only writers jsonRequest = "{\"readers\":[],\"owners\":[]," + "\"writers\":[\"admin-team\"]}"; @@ -99,7 +101,7 @@ public void testPermissions() throws IOException { }.getType()); authInfo = (Map>) resp.get("body"); // Check that owners is set to the princpal if empty - assertEquals(authInfo.get("owners"), Lists.newArrayList("anonymous")); + assertEquals(authInfo.get("owners"), Lists.newArrayList(AuthenticationInfo.ANONYMOUS)); assertEquals(authInfo.get("writers"), Lists.newArrayList("admin-team")); get.releaseConnection(); @@ -119,14 +121,14 @@ public void testPermissions() throws IOException { assertEquals(authInfo.get("owners"), Lists.newArrayList()); get.releaseConnection(); //cleanup - ZeppelinServer.notebook.removeNote(note1.getId(), null); - ZeppelinServer.notebook.removeNote(note2.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note1.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note2.getId(), null); } @Test public void testGetNoteParagraphJobStatus() throws IOException { - Note note1 = ZeppelinServer.notebook.createNote(null); + Note note1 = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); note1.addParagraph(); String paragraphId = note1.getLastParagraph().getId(); @@ -142,13 +144,13 @@ public void testGetNoteParagraphJobStatus() throws IOException { assertEquals(paragraphStatus.get("status"), "READY"); //cleanup - ZeppelinServer.notebook.removeNote(note1.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note1.getId(), null); } @Test public void testCloneNotebook() throws IOException { - Note note1 = ZeppelinServer.notebook.createNote(null); + Note note1 = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); PostMethod post = httpPost("/notebook/" + note1.getId(), ""); LOG.info("testCloneNotebook response\n" + post.getResponseBodyAsString()); assertThat(post, isCreated()); @@ -167,8 +169,8 @@ public void testCloneNotebook() throws IOException { get.releaseConnection(); //cleanup - ZeppelinServer.notebook.removeNote(note1.getId(), null); - ZeppelinServer.notebook.removeNote(clonedNotebookId, null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note1.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(clonedNotebookId, null); } } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/SecurityRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/SecurityRestApiTest.java index b4ecd97e375..c26c9c80c56 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/SecurityRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/SecurityRestApiTest.java @@ -20,6 +20,7 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.zeppelin.user.AuthenticationInfo; import org.hamcrest.CoreMatchers; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -57,9 +58,9 @@ public void testTicket() throws IOException { new TypeToken>(){}.getType()); Map body = (Map) resp.get("body"); collector.checkThat("Paramater principal", body.get("principal"), - CoreMatchers.equalTo("anonymous")); + CoreMatchers.equalTo(AuthenticationInfo.ANONYMOUS)); collector.checkThat("Paramater ticket", body.get("ticket"), - CoreMatchers.equalTo("anonymous")); + CoreMatchers.equalTo(AuthenticationInfo.ANONYMOUS)); get.releaseConnection(); } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java index 4390d74b495..1c6a9fa3216 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java @@ -32,6 +32,8 @@ import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.FixMethodOrder; @@ -77,7 +79,7 @@ public void getApiRoot() throws IOException { public void testGetNotebookInfo() throws IOException { LOG.info("testGetNotebookInfo"); // Create note to get info - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName("note"); Paragraph paragraph = note.addParagraph(); @@ -134,7 +136,7 @@ public void testNotebookCreateWithParagraphs() throws IOException { String newNotebookId = (String) resp.get("body"); LOG.info("newNotebookId:=" + newNotebookId); - Note newNote = ZeppelinServer.notebook.getNote(newNotebookId); + Note newNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(newNotebookId); assertNotNull("Can not find new note by id", newNote); // This is partial test as newNote is in memory but is not persistent String newNoteName = newNote.getName(); @@ -153,7 +155,7 @@ public void testNotebookCreateWithParagraphs() throws IOException { assertTrue("paragraph text check failed", p.getText().startsWith("text")); } // cleanup - ZeppelinServer.notebook.removeNote(newNotebookId, null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(newNotebookId, null); post.releaseConnection(); } @@ -169,7 +171,7 @@ private void testNotebookCreate(String noteName) throws IOException { String newNotebookId = (String) resp.get("body"); LOG.info("newNotebookId:=" + newNotebookId); - Note newNote = ZeppelinServer.notebook.getNote(newNotebookId); + Note newNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(newNotebookId); assertNotNull("Can not find new note by id", newNote); // This is partial test as newNote is in memory but is not persistent String newNoteName = newNote.getName(); @@ -180,7 +182,7 @@ private void testNotebookCreate(String noteName) throws IOException { } assertEquals("compare note name", expectedNoteName, newNoteName); // cleanup - ZeppelinServer.notebook.removeNote(newNotebookId, null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(newNotebookId, null); post.releaseConnection(); } @@ -189,7 +191,7 @@ private void testNotebookCreate(String noteName) throws IOException { public void testDeleteNote() throws IOException { LOG.info("testDeleteNote"); //Create note and get ID - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); String noteId = note.getId(); testDeleteNotebook(noteId); } @@ -205,7 +207,7 @@ public void testDeleteNoteBadId() throws IOException { @Test public void testExportNotebook() throws IOException { LOG.info("testExportNotebook"); - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName("source note for export"); Paragraph paragraph = note.addParagraph(); @@ -227,7 +229,7 @@ public void testExportNotebook() throws IOException { String exportJSON = (String) resp.get("body"); assertNotNull("Can not find new notejson", exportJSON); LOG.info("export JSON:=" + exportJSON); - ZeppelinServer.notebook.removeNote(sourceNoteID, null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(sourceNoteID, null); get.releaseConnection(); } @@ -238,7 +240,7 @@ public void testImportNotebook() throws IOException { String noteName = "source note for import"; LOG.info("testImortNotebook"); // create test notebook - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName(noteName); Paragraph paragraph = note.addParagraph(); @@ -259,13 +261,13 @@ public void testImportNotebook() throws IOException { String importId = (String) resp.get("body"); assertNotNull("Did not get back a notebook id in body", importId); - Note newNote = ZeppelinServer.notebook.getNote(importId); + Note newNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(importId); assertEquals("Compare note names", noteName, newNote.getName()); assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs() .size()); // cleanup - ZeppelinServer.notebook.removeNote(note.getId(), null); - ZeppelinServer.notebook.removeNote(newNote.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(newNote.getId(), null); importPost.releaseConnection(); } @@ -291,7 +293,7 @@ private void testDeleteNotebook(String notebookId) throws IOException { delete.releaseConnection(); // make sure note is deleted if (!notebookId.isEmpty()) { - Note deletedNote = ZeppelinServer.notebook.getNote(notebookId); + Note deletedNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(notebookId); assertNull("Deleted note should be null", deletedNote); } } @@ -300,7 +302,7 @@ private void testDeleteNotebook(String notebookId) throws IOException { public void testCloneNotebook() throws IOException, CloneNotSupportedException, IllegalArgumentException { LOG.info("testCloneNotebook"); // Create note to clone - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName("source note for clone"); Paragraph paragraph = note.addParagraph(); @@ -323,13 +325,13 @@ public void testCloneNotebook() throws IOException, CloneNotSupportedException, String newNotebookId = (String) resp.get("body"); LOG.info("newNotebookId:=" + newNotebookId); - Note newNote = ZeppelinServer.notebook.getNote(newNotebookId); + Note newNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(newNotebookId); assertNotNull("Can not find new note by id", newNote); assertEquals("Compare note names", noteName, newNote.getName()); assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs().size()); //cleanup - ZeppelinServer.notebook.removeNote(note.getId(), null); - ZeppelinServer.notebook.removeNote(newNote.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(newNote.getId(), null); post.releaseConnection(); } @@ -341,7 +343,7 @@ public void testListNotebooks() throws IOException { Map resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken>() { }.getType()); List> body = (List>) resp.get("body"); - assertEquals("List notebooks are equal", ZeppelinServer.notebook.getAllNotes().size(), body.size()); + assertEquals("List notebooks are equal", ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getAllNotes().size(), body.size()); get.releaseConnection(); } @@ -349,7 +351,7 @@ public void testListNotebooks() throws IOException { public void testNoteJobs() throws IOException, InterruptedException { LOG.info("testNoteJobs"); // Create note to run test. - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName("note for run test"); Paragraph paragraph = note.addParagraph(); @@ -397,14 +399,14 @@ public void testNoteJobs() throws IOException, InterruptedException { Thread.sleep(1000); //cleanup - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testGetNotebookJob() throws IOException, InterruptedException { LOG.info("testGetNotebookJob"); // Create note to run test. - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName("note for run test"); Paragraph paragraph = note.addParagraph(); @@ -450,14 +452,14 @@ public void testGetNotebookJob() throws IOException, InterruptedException { } } - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testRunParagraphWithParams() throws IOException, InterruptedException { LOG.info("testRunParagraphWithParams"); // Create note to run test. - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); assertNotNull("can't create new note", note); note.setName("note for run test"); Paragraph paragraph = note.addParagraph(); @@ -488,20 +490,20 @@ public void testRunParagraphWithParams() throws IOException, InterruptedExceptio postParagraph.releaseConnection(); Thread.sleep(1000); - Note retrNote = ZeppelinServer.notebook.getNote(noteID); + Note retrNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(noteID); Paragraph retrParagraph = retrNote.getParagraph(paragraph.getId()); Map params = retrParagraph.settings.getParams(); assertEquals("hello", params.get("param")); assertEquals("world", params.get("param2")); //cleanup - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testCronJobs() throws InterruptedException, IOException{ // create a note and a paragraph - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); note.setName("note for run test"); Paragraph paragraph = note.addParagraph(); @@ -545,12 +547,12 @@ public void testCronJobs() throws InterruptedException, IOException{ DeleteMethod deleteCron = httpDelete("/notebook/cron/" + note.getId()); assertThat("", deleteCron, isAllowed()); deleteCron.releaseConnection(); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testRegressionZEPPELIN_527() throws IOException { - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); note.setName("note for run test"); Paragraph paragraph = note.addParagraph(); @@ -567,12 +569,12 @@ public void testRegressionZEPPELIN_527() throws IOException { assertFalse(body.get(0).containsKey("finished")); getNoteJobs.releaseConnection(); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testInsertParagraph() throws IOException { - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); String jsonRequest = "{\"title\": \"title1\", \"text\": \"text1\"}"; PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest); @@ -586,7 +588,7 @@ public void testInsertParagraph() throws IOException { String newParagraphId = (String) resp.get("body"); LOG.info("newParagraphId:=" + newParagraphId); - Note retrNote = ZeppelinServer.notebook.getNote(note.getId()); + Note retrNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(note.getId()); Paragraph newParagraph = retrNote.getParagraph(newParagraphId); assertNotNull("Can not find new paragraph by id", newParagraph); @@ -607,12 +609,12 @@ public void testInsertParagraph() throws IOException { assertEquals("title2", paragraphAtIdx0.getTitle()); assertEquals("text2", paragraphAtIdx0.getText()); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testGetParagraph() throws IOException { - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); Paragraph p = note.addParagraph(); p.setTitle("hello"); @@ -636,12 +638,12 @@ public void testGetParagraph() throws IOException { assertEquals("hello", body.get("title")); assertEquals("world", body.get("text")); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testMoveParagraph() throws IOException { - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); Paragraph p = note.addParagraph(); p.setTitle("title1"); @@ -657,7 +659,7 @@ public void testMoveParagraph() throws IOException { assertThat("Test post method: ", post, isAllowed()); post.releaseConnection(); - Note retrNote = ZeppelinServer.notebook.getNote(note.getId()); + Note retrNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(note.getId()); Paragraph paragraphAtIdx0 = retrNote.getParagraphs().get(0); assertEquals(p2.getId(), paragraphAtIdx0.getId()); @@ -668,12 +670,12 @@ public void testMoveParagraph() throws IOException { assertThat("Test post method: ", post2, isBadRequest()); post.releaseConnection(); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void testDeleteParagraph() throws IOException { - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); Paragraph p = note.addParagraph(); p.setTitle("title1"); @@ -685,11 +687,11 @@ public void testDeleteParagraph() throws IOException { assertThat("Test delete method: ", delete, isAllowed()); delete.releaseConnection(); - Note retrNote = ZeppelinServer.notebook.getNote(note.getId()); + Note retrNote = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getNote(note.getId()); Paragraph retrParagrah = retrNote.getParagraph(p.getId()); assertNull("paragraph should be deleted", retrParagrah); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test @@ -705,12 +707,12 @@ public void testSearch() throws IOException { String username = body.get("principal"); getSecurityTicket.releaseConnection(); - Note note1 = ZeppelinServer.notebook.createNote(null); + Note note1 = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); String jsonRequest = "{\"title\": \"title1\", \"text\": \"ThisIsToTestSearchMethodWithPermissions 1\"}"; PostMethod postNotebookText = httpPost("/notebook/" + note1.getId() + "/paragraph", jsonRequest); postNotebookText.releaseConnection(); - Note note2 = ZeppelinServer.notebook.createNote(null); + Note note2 = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); jsonRequest = "{\"title\": \"title1\", \"text\": \"ThisIsToTestSearchMethodWithPermissions 2\"}"; postNotebookText = httpPost("/notebook/" + note2.getId() + "/paragraph", jsonRequest); postNotebookText.releaseConnection(); @@ -752,13 +754,13 @@ public void testSearch() throws IOException { getPermission.releaseConnection(); } searchNotebook.releaseConnection(); - ZeppelinServer.notebook.removeNote(note1.getId(), null); - ZeppelinServer.notebook.removeNote(note2.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note1.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note2.getId(), null); } @Test public void testTitleSearch() throws IOException { - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); String jsonRequest = "{\"title\": \"testTitleSearchOfParagraph\", \"text\": \"ThisIsToTestSearchMethodWithTitle \"}"; PostMethod postNotebookText = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest); postNotebookText.releaseConnection(); @@ -779,7 +781,7 @@ public void testTitleSearch() throws IOException { } assertEquals("Paragraph title hits must be at-least one", true, numberOfTitleHits >= 1); searchNotebook.releaseConnection(); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java index 1250f9ce58b..1ed9fcf813a 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java @@ -29,6 +29,8 @@ import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -67,7 +69,7 @@ private void waitForFinish(Paragraph p) { @Test public void basicRDDTransformationAndActionTest() throws IOException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); // run markdown paragraph, again Paragraph p = note.addParagraph(); @@ -79,23 +81,23 @@ public void basicRDDTransformationAndActionTest() throws IOException { waitForFinish(p); assertEquals(Status.FINISHED, p.getStatus()); assertEquals("55", p.getResult().message()); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void sparkRTest() throws IOException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); int sparkVersion = getSparkVersionNumber(note); if (isSparkR() && sparkVersion >= 14) { // sparkr supported from 1.4.0 // restart spark interpreter List settings = - ZeppelinServer.notebook.getBindedInterpreterSettings(note.getId()); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getBindedInterpreterSettings(note.getId()); for (InterpreterSetting setting : settings) { if (setting.getName().equals("spark")) { - ZeppelinServer.notebook.getInterpreterFactory().restart(setting.getId()); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().restart(setting.getId()); break; } } @@ -118,13 +120,13 @@ public void sparkRTest() throws IOException { assertEquals(Status.FINISHED, p.getStatus()); assertEquals("[1] 3", p.getResult().message()); } - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void pySparkTest() throws IOException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); note.setName("note"); int sparkVersion = getSparkVersionNumber(note); @@ -141,13 +143,13 @@ public void pySparkTest() throws IOException { assertEquals(Status.FINISHED, p.getStatus()); assertEquals("55\n", p.getResult().message()); } - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void pySparkAutoConvertOptionTest() throws IOException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); note.setName("note"); int sparkVersionNumber = getSparkVersionNumber(note); @@ -172,13 +174,13 @@ public void pySparkAutoConvertOptionTest() throws IOException { assertEquals(Status.FINISHED, p.getStatus()); assertEquals("10\n", p.getResult().message()); } - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void zRunTest() throws IOException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); Paragraph p0 = note.addParagraph(); Map config0 = p0.getConfig(); config0.put("enabled", true); @@ -204,23 +206,23 @@ public void zRunTest() throws IOException { assertEquals(Status.FINISHED, p2.getStatus()); assertEquals("10", p2.getResult().message()); - ZeppelinServer.notebook.removeNote(note.getId(), null); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).removeNote(note.getId(), null); } @Test public void pySparkDepLoaderTest() throws IOException { // create new note - Note note = ZeppelinServer.notebook.createNote(null); + Note note = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).createNote(null); int sparkVersionNumber = getSparkVersionNumber(note); if (isPyspark() && sparkVersionNumber >= 14) { // restart spark interpreter List settings = - ZeppelinServer.notebook.getBindedInterpreterSettings(note.getId()); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getBindedInterpreterSettings(note.getId()); for (InterpreterSetting setting : settings) { if (setting.getName().equals("spark")) { - ZeppelinServer.notebook.getInterpreterFactory().restart(setting.getId()); + ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS).getInterpreterFactory().restart(setting.getId()); break; } } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java index 01a24e2e1de..9383cecf6f2 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java @@ -31,6 +31,8 @@ import org.apache.zeppelin.notebook.socket.Message.OP; import org.apache.zeppelin.rest.AbstractTestRestApi; import org.apache.zeppelin.server.ZeppelinServer; +import org.apache.zeppelin.session.ZeppelinSessions; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -62,7 +64,7 @@ public class NotebookServerTest extends AbstractTestRestApi { public static void init() throws Exception { AbstractTestRestApi.startUp(); gson = new Gson(); - notebook = ZeppelinServer.notebook; + notebook = ZeppelinSessions.notebook(AuthenticationInfo.ANONYMOUS); notebookServer = ZeppelinServer.notebookWsServer; } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/ticket/TicketContainerTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/ticket/TicketContainerTest.java index 91d2cb3af20..5abdc57cc4b 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/ticket/TicketContainerTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/ticket/TicketContainerTest.java @@ -17,6 +17,7 @@ package org.apache.zeppelin.ticket; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.Before; import org.junit.Test; @@ -35,7 +36,7 @@ public void setUp() throws Exception { @Test public void isValidAnonymous() throws UnknownHostException { - boolean ok = container.isValid("anonymous", "anonymous"); + boolean ok = container.isValid(AuthenticationInfo.ANONYMOUS, AuthenticationInfo.ANONYMOUS); assertTrue(ok); } diff --git a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js index e4f45db0218..bc849190de5 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js +++ b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js @@ -20,6 +20,13 @@ angular.module('zeppelinWebApp').factory('websocketEvents', websocketCalls.ws = $websocket(baseUrlSrv.getWebsocketUrl()); websocketCalls.ws.reconnectIfNotNormalClose = true; + var getQueryString = function(field, url) { + var href = url ? url : window.location.href; + var reg = new RegExp('[?&]' + field + '=([^&#]*)', 'i'); + var string = reg.exec(href); + return string ? string[1] : null; + }; + websocketCalls.ws.onOpen(function() { console.log('Websocket created'); $rootScope.$broadcast('setConnectedStatus', true); @@ -33,6 +40,10 @@ angular.module('zeppelinWebApp').factory('websocketEvents', data.principal = $rootScope.ticket.principal; data.ticket = $rootScope.ticket.ticket; data.roles = $rootScope.ticket.roles; + data.runAs = getQueryString('runAs'); + if (!data.runAs) { + data.runAs = $rootScope.ticket.principal; + } } else { data.principal = ''; data.ticket = ''; diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java index 864b149d379..ea7288f333b 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java @@ -27,6 +27,7 @@ import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.tree.ConfigurationNode; import org.apache.zeppelin.notebook.repo.VFSNotebookRepo; +import org.apache.zeppelin.user.AuthenticationInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -330,8 +331,11 @@ public String getTrustStorePassword() { } } - public String getNotebookDir() { - return getString(ConfVars.ZEPPELIN_NOTEBOOK_DIR); + public String getNotebookDir(AuthenticationInfo authenticationInfo) { + return (isNotebookPeruserNotes()) ? + String.format(getString(ConfVars.ZEPPELIN_NOTEBOOK_DIR) + + "/%s", authenticationInfo.getUser()) : + String.format(getString(ConfVars.ZEPPELIN_NOTEBOOK_DIR)); } public String getUser() { @@ -362,12 +366,15 @@ public String getInterpreterDir() { return getRelativeDir(ConfVars.ZEPPELIN_INTERPRETER_DIR); } - public String getInterpreterJson() { - return getString(ConfVars.ZEPPELIN_INTERPRETER_JSON); + public String getInterpeterSetting() { + return getString(ConfVars.ZEPPELIN_INTERPRETER_SETTING); } - public String getInterpreterSettingPath() { - return getRelativeDir(String.format("%s/interpreter.json", getConfDir())); + public String getInterpreterSettingPath(AuthenticationInfo authenticationInfo) { + return (isNotebookPeruserNotes()) ? + getRelativeDir( + String.format("%s/%s", getNotebookDir(authenticationInfo), getInterpeterSetting())) : + getRelativeDir(String.format("%s/interpreter.json", getConfDir())); } public String getHeliumConfPath() { @@ -378,7 +385,7 @@ public String getHeliumDefaultLocalRegistryPath() { return getRelativeDir(ConfVars.ZEPPELIN_HELIUM_LOCALREGISTRY_DEFAULT); } - public String getNotebookAuthorizationPath() { + public String getNotebookAuthorizationPath(AuthenticationInfo authenticationInfo) { return getRelativeDir(String.format("%s/notebook-authorization.json", getConfDir())); } @@ -435,6 +442,14 @@ public String getWebsocketMaxTextMessageSize() { return getString(ConfVars.ZEPPELIN_WEBSOCKET_MAX_TEXT_MESSAGE_SIZE); } + public boolean isNotebookPeruserNotes() { + return getBoolean(ConfVars.ZEPPELIN_NOTEBOOK_PERUSER_NOTES); + } + + public boolean isInterpreterPeruserFactories() { + return getBoolean(ConfVars.ZEPPELIN_INTERPRETER_PERUSER_FACTORIES); + } + public Map dumpConfigurations(ZeppelinConfiguration conf, ConfigurationKeyPredicate predicate) { Map configurations = new HashMap<>(); @@ -524,7 +539,7 @@ public static enum ConfVars { + "org.apache.zeppelin.jdbc.JDBCInterpreter," + "org.apache.zeppelin.hbase.HbaseInterpreter," + "org.apache.zeppelin.bigquery.BigQueryInterpreter"), - ZEPPELIN_INTERPRETER_JSON("zeppelin.interpreter.setting", "interpreter-setting.json"), + ZEPPELIN_INTERPRETER_SETTING("zeppelin.interpreter.setting", "interpreter-setting.json"), ZEPPELIN_INTERPRETER_DIR("zeppelin.interpreter.dir", "interpreter"), ZEPPELIN_INTERPRETER_LOCALREPO("zeppelin.interpreter.localRepo", "local-repo"), ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT("zeppelin.interpreter.connect.timeout", 30000), @@ -561,7 +576,10 @@ public static enum ConfVars { ZEPPELIN_ALLOWED_ORIGINS("zeppelin.server.allowed.origins", "*"), ZEPPELIN_ANONYMOUS_ALLOWED("zeppelin.anonymous.allowed", true), ZEPPELIN_CREDENTIALS_PERSIST("zeppelin.credentials.persist", true), - ZEPPELIN_WEBSOCKET_MAX_TEXT_MESSAGE_SIZE("zeppelin.websocket.max.text.message.size", "1024000"); + ZEPPELIN_WEBSOCKET_MAX_TEXT_MESSAGE_SIZE("zeppelin.websocket.max.text.message.size", "1024000"), + ZEPPELIN_NOTEBOOK_PERUSER_NOTES("zeppelin.notebook.peruser.notes", false), + ZEPPELIN_INTERPRETER_PERUSER_FACTORIES("zeppelin.interpreter.peruser.factories", false) + ; private String varName; @SuppressWarnings("rawtypes") 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 ab67b5b5331..a7ca9b0958b 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 @@ -56,6 +56,7 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.NullArgumentException; import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.user.AuthenticationInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonatype.aether.RepositoryException; @@ -105,6 +106,8 @@ public class InterpreterFactory implements InterpreterGroupFactory { */ private final Map interpreterSettings = new HashMap<>(); + private AuthenticationInfo authenticationInfo; + private Map> interpreterBindings = new HashMap<>(); private List interpreterRepositories; @@ -125,17 +128,19 @@ public class InterpreterFactory implements InterpreterGroupFactory { public InterpreterFactory(ZeppelinConfiguration conf, AngularObjectRegistryListener angularObjectRegistryListener, RemoteInterpreterProcessListener remoteInterpreterProcessListener, - ApplicationEventListener appEventListener, DependencyResolver depResolver) + ApplicationEventListener appEventListener, DependencyResolver depResolver, + AuthenticationInfo authenticationInfo) throws InterpreterException, IOException, RepositoryException { this(conf, new InterpreterOption(true), angularObjectRegistryListener, - remoteInterpreterProcessListener, appEventListener, depResolver); + remoteInterpreterProcessListener, appEventListener, depResolver, authenticationInfo); } public InterpreterFactory(ZeppelinConfiguration conf, InterpreterOption defaultOption, AngularObjectRegistryListener angularObjectRegistryListener, RemoteInterpreterProcessListener remoteInterpreterProcessListener, - ApplicationEventListener appEventListener, DependencyResolver depResolver) + ApplicationEventListener appEventListener, DependencyResolver depResolver, + AuthenticationInfo authenticationInfo) throws InterpreterException, IOException, RepositoryException { this.conf = conf; this.defaultOption = defaultOption; @@ -144,6 +149,8 @@ public InterpreterFactory(ZeppelinConfiguration conf, InterpreterOption defaultO this.interpreterRepositories = depResolver.getRepos(); this.remoteInterpreterProcessListener = remoteInterpreterProcessListener; this.appEventListener = appEventListener; + this.authenticationInfo = authenticationInfo; + String replsConf = conf.getString(ConfVars.ZEPPELIN_INTERPRETERS); interpreterClassList = replsConf.split(","); String groupOrder = conf.getString(ConfVars.ZEPPELIN_INTERPRETER_GROUP_ORDER); @@ -157,7 +164,7 @@ public InterpreterFactory(ZeppelinConfiguration conf, InterpreterOption defaultO } private void init() throws InterpreterException, IOException, RepositoryException { - String interpreterJson = conf.getInterpreterJson(); + String interpreterJson = conf.getInterpeterSetting(); ClassLoader cl = Thread.currentThread().getContextClassLoader(); Path interpretersDir = Paths.get(conf.getInterpreterDir()); @@ -223,7 +230,7 @@ public boolean accept(Path entry) throws IOException { logger.info("InterpreterSettingRef name {}", setting.getName()); } - loadFromFile(); + loadSettingsFromFile(); // if no interpreter settings are loaded, create default set if (0 == interpreterSettings.size()) { @@ -244,7 +251,7 @@ public boolean accept(Path entry) throws IOException { interpreterSettings.put(setting.getId(), setting); } - saveToFile(); + saveSettingsToFile(); } @@ -336,8 +343,8 @@ private void registerInterpreters(List registeredInterpre } - private void loadFromFile() throws IOException { - File settingFile = new File(conf.getInterpreterSettingPath()); + private void loadSettingsFromFile() throws IOException { + File settingFile = new File(conf.getInterpreterSettingPath(authenticationInfo)); if (!settingFile.exists()) { // nothing to read return; @@ -440,7 +447,7 @@ public void run() { } } - private void saveToFile() throws IOException { + private void saveSettingsToFile() throws IOException { String jsonString; synchronized (interpreterSettings) { @@ -452,8 +459,9 @@ private void saveToFile() throws IOException { jsonString = gson.toJson(info); } - File settingFile = new File(conf.getInterpreterSettingPath()); + File settingFile = new File(conf.getInterpreterSettingPath(authenticationInfo)); if (!settingFile.exists()) { + settingFile.getParentFile().mkdirs(); settingFile.createNewFile(); } @@ -517,7 +525,7 @@ public InterpreterSetting createNewSetting(String name, String group, setting.setProperties(p); setting.setInterpreterGroupFactory(this); interpreterSettings.put(setting.getId(), setting); - saveToFile(); + saveSettingsToFile(); return setting; } @@ -718,7 +726,7 @@ public void remove(String id) throws IOException { } } } - saveToFile(); + saveSettingsToFile(); } } @@ -795,7 +803,7 @@ private void putNoteInterpreterSettingBinding(String noteId, List settin } } interpreterBindings.put(noteId, settingList); - saveToFile(); + saveSettingsToFile(); for (String settingId : unBindedSettings) { InterpreterSetting setting = get(settingId); @@ -849,7 +857,7 @@ public void setPropertyAndRestart(String id, InterpreterOption option, Propertie intpsetting.setDependencies(dependencies); loadInterpreterDependencies(intpsetting); - saveToFile(); + saveSettingsToFile(); } else { throw new InterpreterException("Interpreter setting id " + id + " not found"); } @@ -1226,12 +1234,12 @@ public List getRepositories() { public void addRepository(String id, String url, boolean snapshot, Authentication auth) throws IOException { depResolver.addRepo(id, url, snapshot, auth); - saveToFile(); + saveSettingsToFile(); } public void removeRepository(String id) throws IOException { depResolver.delRepo(id); - saveToFile(); + saveSettingsToFile(); } public Map getEnv() { 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 ae448e3947f..2145b8ac24a 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 @@ -74,7 +74,7 @@ public class Notebook implements NoteEventListener { @SuppressWarnings("unused") @Deprecated //TODO(bzz): remove unused private SchedulerFactory schedulerFactory; - private InterpreterFactory replFactory; + private InterpreterFactory interpreterFactory; /** * Keep the order. */ @@ -98,14 +98,14 @@ public class Notebook implements NoteEventListener { * @throws SchedulerException */ public Notebook(ZeppelinConfiguration conf, NotebookRepo notebookRepo, - SchedulerFactory schedulerFactory, InterpreterFactory replFactory, + SchedulerFactory schedulerFactory, InterpreterFactory interpreterFactory, JobListenerFactory jobListenerFactory, SearchService notebookIndex, NotebookAuthorization notebookAuthorization, Credentials credentials) throws IOException, SchedulerException { this.conf = conf; this.notebookRepo = notebookRepo; this.schedulerFactory = schedulerFactory; - this.replFactory = replFactory; + this.interpreterFactory = interpreterFactory; this.jobListenerFactory = jobListenerFactory; this.notebookIndex = notebookIndex; this.notebookAuthorization = notebookAuthorization; @@ -134,7 +134,7 @@ public Notebook(ZeppelinConfiguration conf, NotebookRepo notebookRepo, public Note createNote(AuthenticationInfo subject) throws IOException { Note note; if (conf.getBoolean(ConfVars.ZEPPELIN_NOTEBOOK_AUTO_INTERPRETER_BINDING)) { - note = createNote(replFactory.getDefaultInterpreterSettingList(), subject); + note = createNote(interpreterFactory.getDefaultInterpreterSettingList(), subject); } else { note = createNote(null, subject); } @@ -150,7 +150,8 @@ public Note createNote(AuthenticationInfo subject) throws IOException { public Note createNote(List interpreterIds, AuthenticationInfo subject) throws IOException { Note note = - new Note(notebookRepo, replFactory, jobListenerFactory, notebookIndex, credentials, this); + new Note(notebookRepo, interpreterFactory, + jobListenerFactory, notebookIndex, credentials, this); synchronized (notes) { notes.put(note.getId(), note); } @@ -260,16 +261,16 @@ public void bindInterpretersToNote(String id, List interpreterSettingIds throws IOException { Note note = getNote(id); if (note != null) { - List currentBindings = replFactory.getInterpreterSettings(id); + List currentBindings = interpreterFactory.getInterpreterSettings(id); for (InterpreterSetting setting : currentBindings) { if (!interpreterSettingIds.contains(setting.getId())) { fireUnbindInterpreter(note, setting); } } - replFactory.setInterpreters(note.getId(), interpreterSettingIds); + interpreterFactory.setInterpreters(note.getId(), interpreterSettingIds); // comment out while note.getNoteReplLoader().setInterpreters(...) do the same - // replFactory.putNoteInterpreterSettingBinding(id, interpreterSettingIds); + // interpreterFactory.putNoteInterpreterSettingBinding(id, interpreterSettingIds); } } @@ -285,7 +286,7 @@ List getBindedInterpreterSettingsIds(String id) { public List getBindedInterpreterSettings(String id) { Note note = getNote(id); if (note != null) { - return replFactory.getInterpreterSettings(note.getId()); + return interpreterFactory.getInterpreterSettings(note.getId()); } else { return new LinkedList<>(); } @@ -303,12 +304,12 @@ public void removeNote(String id, AuthenticationInfo subject) { synchronized (notes) { note = notes.remove(id); } - replFactory.removeNoteInterpreterSettingBinding(id); + interpreterFactory.removeNoteInterpreterSettingBinding(id); notebookIndex.deleteIndexDocs(note); notebookAuthorization.removeNote(id); // remove from all interpreter instance's angular object registry - for (InterpreterSetting settings : replFactory.get()) { + for (InterpreterSetting settings : interpreterFactory.get()) { AngularObjectRegistry registry = settings.getInterpreterGroup(id).getAngularObjectRegistry(); if (registry instanceof RemoteAngularObjectRegistry) { // remove paragraph scope object @@ -386,7 +387,7 @@ private Note loadNoteFromRepo(String id, AuthenticationInfo subject) { note.setIndex(this.notebookIndex); note.setCredentials(this.credentials); - note.setInterpreterFactory(replFactory); + note.setInterpreterFactory(interpreterFactory); note.setJobListenerFactory(jobListenerFactory); note.setNotebookRepo(notebookRepo); @@ -427,7 +428,7 @@ private Note loadNoteFromRepo(String id, AuthenticationInfo subject) { for (String name : angularObjectSnapshot.keySet()) { SnapshotAngularObject snapshot = angularObjectSnapshot.get(name); - List settings = replFactory.get(); + List settings = interpreterFactory.get(); for (InterpreterSetting setting : settings) { InterpreterGroup intpGroup = setting.getInterpreterGroup(note.getId()); if (intpGroup.getId().equals(snapshot.getIntpGroupId())) { @@ -630,9 +631,9 @@ public List> getJobListBymNotebookId(String notebookID) { // set interpreter bind type String interpreterGroupName = null; - if (replFactory.getInterpreterSettings(jobNote.getId()) != null - && replFactory.getInterpreterSettings(jobNote.getId()).size() >= 1) { - interpreterGroupName = replFactory.getInterpreterSettings(jobNote.getId()).get(0).getName(); + if (interpreterFactory.getInterpreterSettings(jobNote.getId()) != null + && interpreterFactory.getInterpreterSettings(jobNote.getId()).size() >= 1) { + interpreterGroupName = interpreterFactory.getInterpreterSettings(jobNote.getId()).get(0).getName(); } // notebook json object root information. @@ -706,9 +707,10 @@ public List> getJobListByUnixTime(boolean needsReload, // set interpreter bind type String interpreterGroupName = null; - if (replFactory.getInterpreterSettings(note.getId()) != null - && replFactory.getInterpreterSettings(note.getId()).size() >= 1) { - interpreterGroupName = replFactory.getInterpreterSettings(note.getId()).get(0).getName(); + if (interpreterFactory.getInterpreterSettings(note.getId()) != null + && interpreterFactory.getInterpreterSettings(note.getId()).size() >= 1) { + interpreterGroupName = interpreterFactory + .getInterpreterSettings(note.getId()).get(0).getName(); } // not update and not running -> pass @@ -822,13 +824,17 @@ private void removeCron(String id) { } public InterpreterFactory getInterpreterFactory() { - return replFactory; + return interpreterFactory; } public NotebookAuthorization getNotebookAuthorization() { return notebookAuthorization; } + public NotebookRepo getNotebookRepo() { + return this.notebookRepo; + } + public ZeppelinConfiguration getConf() { return conf; } 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 0633906d110..8320a61dd0a 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 @@ -20,6 +20,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.apache.zeppelin.conf.ZeppelinConfiguration; +import org.apache.zeppelin.user.AuthenticationInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,8 +42,12 @@ public class NotebookAuthorization { private String filePath; public NotebookAuthorization(ZeppelinConfiguration conf) { + this(conf, null); + } + + public NotebookAuthorization(ZeppelinConfiguration conf, AuthenticationInfo authenticationInfo) { this.conf = conf; - filePath = conf.getNotebookAuthorizationPath(); + filePath = conf.getNotebookAuthorizationPath(authenticationInfo); GsonBuilder builder = new GsonBuilder(); builder.setPrettyPrinting(); gson = builder.create(); 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 ca72fc1f7f0..ec570631e54 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 @@ -51,7 +51,7 @@ public class AzureNotebookRepo implements NotebookRepo { private final String shareName; private final CloudFileDirectory rootDir; - public AzureNotebookRepo(ZeppelinConfiguration conf) + public AzureNotebookRepo(ZeppelinConfiguration conf, AuthenticationInfo authenticationInfo) throws URISyntaxException, InvalidKeyException, StorageException { this.conf = conf; user = conf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_NOTEBOOK_AZURE_USER); diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java index b0678dd4795..25081a0589e 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java @@ -57,8 +57,9 @@ public class GitNotebookRepo extends VFSNotebookRepo { private String localPath; private Git git; - public GitNotebookRepo(ZeppelinConfiguration conf) throws IOException { - super(conf); + public GitNotebookRepo(ZeppelinConfiguration conf, + AuthenticationInfo authenticationInfo) throws IOException { + super(conf, authenticationInfo); localPath = getRootDir().getName().getPath(); LOG.info("Opening a git repo at '{}'", localPath); Repository localRepo = new FileRepository(Joiner.on(File.separator).join(localPath, ".git")); diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java index 72087262aca..e88c53cb885 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java @@ -58,7 +58,7 @@ public class NotebookRepoSync implements NotebookRepo { * @throws - Exception */ @SuppressWarnings("static-access") - public NotebookRepoSync(ZeppelinConfiguration conf) { + public NotebookRepoSync(ZeppelinConfiguration conf, AuthenticationInfo authenticationInfo) { config = conf; oneWaySync = conf.getBoolean(ConfVars.ZEPPELIN_NOTEBOOK_ONE_WAY_SYNC); String allStorageClassNames = conf.getString(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE).trim(); @@ -78,8 +78,8 @@ public NotebookRepoSync(ZeppelinConfiguration conf) { try { notebookStorageClass = getClass().forName(storageClassNames[i].trim()); Constructor constructor = notebookStorageClass.getConstructor( - ZeppelinConfiguration.class); - repos.add((NotebookRepo) constructor.newInstance(conf)); + ZeppelinConfiguration.class, AuthenticationInfo.class); + repos.add((NotebookRepo) constructor.newInstance(conf, authenticationInfo)); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 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 0163fc4b859..ac19c658a78 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 @@ -82,7 +82,8 @@ public class S3NotebookRepo implements NotebookRepo { private final String user; private final ZeppelinConfiguration conf; - public S3NotebookRepo(ZeppelinConfiguration conf) throws IOException { + public S3NotebookRepo(ZeppelinConfiguration conf, + AuthenticationInfo authenticationInfo) throws IOException { this.conf = conf; bucketName = conf.getBucketName(); user = conf.getUser(); 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 213fdf87e95..d205bfe1dfe 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 @@ -60,14 +60,15 @@ public class VFSNotebookRepo implements NotebookRepo { private URI filesystemRoot; private ZeppelinConfiguration conf; - public VFSNotebookRepo(ZeppelinConfiguration conf) throws IOException { + public VFSNotebookRepo(ZeppelinConfiguration conf, + AuthenticationInfo authenticationInfo) throws IOException { this.conf = conf; try { - if (conf.isWindowsPath(conf.getNotebookDir())) { - filesystemRoot = new File(conf.getNotebookDir()).toURI(); + if (conf.isWindowsPath(conf.getNotebookDir(authenticationInfo))) { + filesystemRoot = new File(conf.getNotebookDir(authenticationInfo)).toURI(); } else { - filesystemRoot = new URI(conf.getNotebookDir()); + filesystemRoot = new URI(conf.getNotebookDir(authenticationInfo)); } } catch (URISyntaxException e1) { throw new IOException(e1); diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java index d1864c5c7dc..91318b3acbf 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java @@ -54,7 +54,7 @@ public class ZeppelinHubRepo implements NotebookRepo { private String token; private ZeppelinhubRestApiHandler restApiClient; - public ZeppelinHubRepo(ZeppelinConfiguration conf) { + public ZeppelinHubRepo(ZeppelinConfiguration conf, AuthenticationInfo authenticationInfo) { String zeppelinHubUrl = getZeppelinHubUrl(conf); LOG.info("Initializing ZeppelinHub integration module"); token = conf.getString("ZEPPELINHUB_API_TOKEN", ZEPPELIN_CONF_PROP_NAME_TOKEN, ""); diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java index 4b8b42d2b4d..2d56dd4dc8d 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java @@ -22,6 +22,7 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.notebook.socket.Message; import org.apache.zeppelin.notebook.socket.Message.OP; +import org.apache.zeppelin.user.AuthenticationInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,8 +35,8 @@ */ public class Authentication implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(Authentication.class); - private String principal = "anonymous"; - private String ticket = "anonymous"; + private String principal = AuthenticationInfo.ANONYMOUS; + private String ticket = AuthenticationInfo.ANONYMOUS; private String roles = StringUtils.EMPTY; private final HttpClient client; 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 9175e308c3e..289ab6551f0 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,6 +17,8 @@ package org.apache.zeppelin.notebook.socket; +import org.apache.zeppelin.user.AuthenticationInfo; + import java.util.HashMap; import java.util.Map; @@ -139,9 +141,10 @@ public static enum OP { public OP op; public Map data = new HashMap(); - public String ticket = "anonymous"; - public String principal = "anonymous"; + public String ticket = AuthenticationInfo.ANONYMOUS; + public String principal = AuthenticationInfo.ANONYMOUS; public String roles = ""; + public String runAs = AuthenticationInfo.ANONYMOUS; public Message(OP op) { this.op = op; diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java index f9d8ca3d214..1253cd79076 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java @@ -21,6 +21,7 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.Before; import org.junit.Test; @@ -84,7 +85,7 @@ public void isWindowsPathTestFalse() throws ConfigurationException { public void getNotebookDirTest() throws ConfigurationException { ZeppelinConfiguration conf = new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml")); - String notebookLocation = conf.getNotebookDir(); + String notebookLocation = conf.getNotebookDir(AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); Assert.assertEquals("notebook", notebookLocation); } } diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java index b32b3d8feb2..d1893d8f8d1 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java @@ -27,6 +27,7 @@ import org.apache.zeppelin.scheduler.Job; 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; @@ -82,14 +83,14 @@ public void setUp() throws Exception { heliumAppFactory = new HeliumApplicationFactory(); depResolver = new DependencyResolver(tmpDir.getAbsolutePath() + "/local-repo"); factory = new InterpreterFactory(conf, - new InterpreterOption(true), null, null, heliumAppFactory, depResolver); + new InterpreterOption(true), null, null, heliumAppFactory, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); HashMap env = new HashMap(); env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath()); factory.setEnv(env); SearchService search = mock(SearchService.class); - notebookRepo = new VFSNotebookRepo(conf); - NotebookAuthorization notebookAuthorization = new NotebookAuthorization(conf); + notebookRepo = new VFSNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); + NotebookAuthorization notebookAuthorization = new NotebookAuthorization(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); notebook = new Notebook( conf, notebookRepo, 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 5cdda05a499..15b133983fd 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 @@ -33,6 +33,7 @@ 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.junit.After; import org.junit.Before; @@ -65,7 +66,7 @@ public void setUp() throws Exception { System.setProperty(ConfVars.ZEPPELIN_INTERPRETERS.getVarName(), "org.apache.zeppelin.interpreter.mock.MockInterpreter1,org.apache.zeppelin.interpreter.mock.MockInterpreter2"); conf = new ZeppelinConfiguration(); depResolver = new DependencyResolver(tmpDir.getAbsolutePath() + "/local-repo"); - factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver); + factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); context = new InterpreterContext("note", "id", "title", "text", null, null, null, null, null, null, null); } @@ -103,7 +104,7 @@ public void testBasic() { @Test public void testRemoteRepl() throws Exception { - factory = new InterpreterFactory(conf, new InterpreterOption(true), null, null, null, depResolver); + factory = new InterpreterFactory(conf, new InterpreterOption(true), null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); List all = factory.get(); InterpreterSetting mock1Setting = null; for (InterpreterSetting setting : all) { @@ -154,18 +155,18 @@ public void testSaveLoad() throws IOException, RepositoryException { int numInterpreters = factory.get().size(); // check if file saved - assertTrue(new File(conf.getInterpreterSettingPath()).exists()); + assertTrue(new File(conf.getInterpreterSettingPath(AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO)).exists()); factory.createNewSetting("new-mock1", "mock1", new LinkedList(), new InterpreterOption(false), new Properties()); assertEquals(numInterpreters + 1, factory.get().size()); - InterpreterFactory factory2 = new InterpreterFactory(conf, null, null, null, depResolver); + InterpreterFactory factory2 = new InterpreterFactory(conf, null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertEquals(numInterpreters + 1, factory2.get().size()); } @Test public void testInterpreterAliases() throws IOException, RepositoryException { - factory = new InterpreterFactory(conf, null, null, null, depResolver); + factory = new InterpreterFactory(conf, null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); final InterpreterInfo info1 = new InterpreterInfo("className1", "name1", true); final InterpreterInfo info2 = new InterpreterInfo("className2", "name1", true); factory.add("group1", new ArrayList(){{ diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteInterpreterLoaderTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteInterpreterLoaderTest.java index 245089963ea..04060f1ace1 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteInterpreterLoaderTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NoteInterpreterLoaderTest.java @@ -30,6 +30,7 @@ import org.apache.zeppelin.interpreter.mock.MockInterpreter1; import org.apache.zeppelin.interpreter.mock.MockInterpreter11; import org.apache.zeppelin.interpreter.mock.MockInterpreter2; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -60,7 +61,7 @@ public void setUp() throws Exception { MockInterpreter2.register("mock2", "group2", "org.apache.zeppelin.interpreter.mock.MockInterpreter2"); depResolver = new DependencyResolver(tmpDir.getAbsolutePath() + "/local-repo"); - factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver); + factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); } @After 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 648062eda2e..1335de59c1c 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 @@ -42,6 +42,7 @@ import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.scheduler.SchedulerFactory; import org.apache.zeppelin.search.SearchService; +import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.user.Credentials; import org.junit.After; import org.junit.Before; @@ -86,11 +87,11 @@ public void setUp() throws Exception { MockInterpreter2.register("mock2", "org.apache.zeppelin.interpreter.mock.MockInterpreter2"); depResolver = new DependencyResolver(tmpDir.getAbsolutePath() + "/local-repo"); - factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver); + factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); SearchService search = mock(SearchService.class); - notebookRepo = new VFSNotebookRepo(conf); - notebookAuthorization = new NotebookAuthorization(conf); + notebookRepo = new VFSNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); + notebookAuthorization = new NotebookAuthorization(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath()); notebook = new Notebook(conf, notebookRepo, schedulerFactory, factory, this, search, @@ -205,7 +206,7 @@ public void testPersist() throws IOException, SchedulerException, RepositoryExce Notebook notebook2 = new Notebook( conf, notebookRepo, schedulerFactory, - new InterpreterFactory(conf, null, null, null, depResolver), this, null, null, null); + new InterpreterFactory(conf, null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO), this, null, null, null); assertEquals(1, notebook2.getAllNotes().size()); } diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java index 2e96615329b..4ad3f020ae0 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java @@ -34,6 +34,7 @@ import org.apache.zeppelin.notebook.NoteInfo; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision; +import org.apache.zeppelin.user.AuthenticationInfo; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffEntry; @@ -95,7 +96,7 @@ public void initNonemptyNotebookDir() throws IOException, GitAPIException { assertThat(dotGit.exists()).isEqualTo(false); //when - notebookRepo = new GitNotebookRepo(conf); + notebookRepo = new GitNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); //then Git git = notebookRepo.getGit(); @@ -112,7 +113,7 @@ public void initNonemptyNotebookDir() throws IOException, GitAPIException { @Test public void showNotebookHistoryEmptyTest() throws GitAPIException, IOException { //given - notebookRepo = new GitNotebookRepo(conf); + notebookRepo = new GitNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(notebookRepo.list(null)).isNotEmpty(); //when @@ -126,7 +127,7 @@ public void showNotebookHistoryEmptyTest() throws GitAPIException, IOException { @Test public void showNotebookHistoryMultipleNotesTest() throws IOException { //initial checks - notebookRepo = new GitNotebookRepo(conf); + notebookRepo = new GitNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(notebookRepo.list(null)).isNotEmpty(); assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID)).isTrue(); assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID2)).isTrue(); @@ -169,7 +170,7 @@ public void showNotebookHistoryMultipleNotesTest() throws IOException { @Test public void addCheckpointTest() throws IOException { // initial checks - notebookRepo = new GitNotebookRepo(conf); + notebookRepo = new GitNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(notebookRepo.list(null)).isNotEmpty(); assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID)).isTrue(); assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null)).isEmpty(); @@ -208,7 +209,7 @@ private boolean containsNote(List notes, String noteId) { @Test public void getRevisionTest() throws IOException { // initial checks - notebookRepo = new GitNotebookRepo(conf); + notebookRepo = new GitNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(notebookRepo.list(null)).isNotEmpty(); assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID)).isTrue(); assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null)).isEmpty(); @@ -263,7 +264,7 @@ public void getRevisionTest() throws IOException { @Test public void getRevisionFailTest() throws IOException { // initial checks - notebookRepo = new GitNotebookRepo(conf); + notebookRepo = new GitNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(notebookRepo.list(null)).isNotEmpty(); assertThat(containsNote(notebookRepo.list(null), TEST_NOTE_ID)).isTrue(); assertThat(notebookRepo.revisionHistory(TEST_NOTE_ID, null)).isEmpty(); diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java index 53c052a43d2..a986928f616 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java @@ -26,6 +26,7 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.notebook.repo.mock.VFSNotebookRepoMock; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -60,7 +61,7 @@ public void validInitOneStorageTest() throws IOException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), validOneStorageConf); ZeppelinConfiguration conf = ZeppelinConfiguration.create(); // create repo - NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf); + NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); // check proper initialization of one storage assertEquals(notebookRepoSync.getRepoCount(), 1); assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo); @@ -86,7 +87,7 @@ public void validInitTwoStorageTest() throws IOException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), validTwoStorageConf); ZeppelinConfiguration conf = ZeppelinConfiguration.create(); // create repo - NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf); + NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); // check that both initialized assertEquals(notebookRepoSync.getRepoCount(), 2); assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo); @@ -99,7 +100,7 @@ public void invalidInitTwoStorageTest() throws IOException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), invalidTwoStorageConf); ZeppelinConfiguration conf = ZeppelinConfiguration.create(); // create repo - NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf); + NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); // check that second didn't initialize LOG.info(" " + notebookRepoSync.getRepoCount()); assertEquals(notebookRepoSync.getRepoCount(), 1); @@ -126,7 +127,7 @@ public void initUnsupportedNumberStoragesTest() throws IOException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), unsupportedStorageConf); ZeppelinConfiguration conf = ZeppelinConfiguration.create(); // create repo - NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf); + NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); // check that first two storages initialized instead of three assertEquals(notebookRepoSync.getRepoCount(), 2); assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo); @@ -139,7 +140,7 @@ public void initEmptyStorageTest() throws IOException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), emptyStorageConf); ZeppelinConfiguration conf = ZeppelinConfiguration.create(); // create repo - NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf); + NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); // check initialization of one default storage assertEquals(notebookRepoSync.getRepoCount(), 1); assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo); @@ -151,7 +152,7 @@ public void initOneDummyStorageTest() throws IOException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), invalidStorageClass); ZeppelinConfiguration conf = ZeppelinConfiguration.create(); // create repo - NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf); + NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); // check initialization of one default storage instead of invalid one assertEquals(notebookRepoSync.getRepoCount(), 1); assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo); diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java index bd13120a4a3..c0b41cde553 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java @@ -42,6 +42,7 @@ import org.apache.zeppelin.scheduler.SchedulerFactory; import org.apache.zeppelin.search.SearchService; import org.apache.zeppelin.search.LuceneSearch; +import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.user.Credentials; import org.junit.After; import org.junit.Before; @@ -95,11 +96,11 @@ public void setUp() throws Exception { MockInterpreter2.register("mock2", "org.apache.zeppelin.interpreter.mock.MockInterpreter2"); depResolver = new DependencyResolver(mainZepDir.getAbsolutePath() + "/local-repo"); - factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver); + factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); search = mock(SearchService.class); - notebookRepoSync = new NotebookRepoSync(conf); - notebookAuthorization = new NotebookAuthorization(conf); + notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); + notebookAuthorization = new NotebookAuthorization(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath()); notebookSync = new Notebook(conf, notebookRepoSync, schedulerFactory, factory, this, search, notebookAuthorization, credentials); @@ -226,7 +227,7 @@ public void testOneWaySyncOnReloadedList() throws IOException, SchedulerExceptio System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_DIR.getVarName(), mainNotebookDir.getAbsolutePath()); System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_ONE_WAY_SYNC.getVarName(), "true"); conf = ZeppelinConfiguration.create(); - notebookRepoSync = new NotebookRepoSync(conf); + notebookRepoSync = new NotebookRepoSync(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); notebookSync = new Notebook(conf, notebookRepoSync, schedulerFactory, factory, this, search, notebookAuthorization, credentials); @@ -274,7 +275,7 @@ public void testCheckpointOneStorage() throws IOException, SchedulerException { System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), "org.apache.zeppelin.notebook.repo.GitNotebookRepo"); ZeppelinConfiguration vConf = ZeppelinConfiguration.create(); - NotebookRepoSync vRepoSync = new NotebookRepoSync(vConf); + NotebookRepoSync vRepoSync = new NotebookRepoSync(vConf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); Notebook vNotebookSync = new Notebook(vConf, vRepoSync, schedulerFactory, factory, this, search, notebookAuthorization, credentials); diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepoTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepoTest.java index 7eaca8c74eb..6299f3be2a7 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepoTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepoTest.java @@ -36,6 +36,7 @@ import org.apache.zeppelin.scheduler.SchedulerFactory; import org.apache.zeppelin.search.SearchService; import org.apache.zeppelin.search.LuceneSearch; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -76,10 +77,10 @@ public void setUp() throws Exception { this.schedulerFactory = new SchedulerFactory(); depResolver = new DependencyResolver(mainZepDir.getAbsolutePath() + "/local-repo"); - factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver); + factory = new InterpreterFactory(conf, new InterpreterOption(false), null, null, null, depResolver, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); SearchService search = mock(SearchService.class); - notebookRepo = new VFSNotebookRepo(conf); + notebookRepo = new VFSNotebookRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); notebook = new Notebook(conf, notebookRepo, schedulerFactory, factory, this, search, null, null); } diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/mock/VFSNotebookRepoMock.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/mock/VFSNotebookRepoMock.java index 2674cce07ff..156d98156da 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/mock/VFSNotebookRepoMock.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/mock/VFSNotebookRepoMock.java @@ -25,18 +25,19 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.notebook.repo.VFSNotebookRepo; +import org.apache.zeppelin.user.AuthenticationInfo; public class VFSNotebookRepoMock extends VFSNotebookRepo { private static ZeppelinConfiguration modifyNotebookDir(ZeppelinConfiguration conf) { - String secNotebookDir = conf.getNotebookDir() + "_secondary"; + String secNotebookDir = conf.getNotebookDir(AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO) + "_secondary"; System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_DIR.getVarName(), secNotebookDir); ZeppelinConfiguration secConf = ZeppelinConfiguration.create(); return secConf; } public VFSNotebookRepoMock(ZeppelinConfiguration conf) throws IOException { - super(modifyNotebookDir(conf)); + super(modifyNotebookDir(conf), AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); } } diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepoTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepoTest.java index 720dd702faa..8f6e014a511 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepoTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepoTest.java @@ -13,6 +13,7 @@ import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.NoteInfo; import org.apache.zeppelin.notebook.repo.zeppelinhub.rest.ZeppelinhubRestApiHandler; +import org.apache.zeppelin.user.AuthenticationInfo; import org.junit.Before; import org.junit.Test; @@ -33,7 +34,7 @@ public void setUp() throws Exception { System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_TOKEN, "AAA-BBB-CCC-00"); ZeppelinConfiguration conf = new ZeppelinConfiguration(); - repo = new ZeppelinHubRepo(conf); + repo = new ZeppelinHubRepo(conf, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); repo.setZeppelinhubRestApiHandler(getMockedZeppelinHandler()); } @@ -54,25 +55,25 @@ public void testGetZeppelinhubUrl() { System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, testAddr); ZeppelinConfiguration config = new ZeppelinConfiguration(); - ZeppelinHubRepo repository = new ZeppelinHubRepo(config); + ZeppelinHubRepo repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinHubUrl(config)).isEqualTo("http://zeppelinhub.ltd"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "yolow"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinHubUrl(config)).isEqualTo("https://www.zeppelinhub.com"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "http://zeppelinhub.ltd:4242"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinHubUrl(config)).isEqualTo("http://zeppelinhub.ltd:4242"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "http://zeppelinhub.ltd:0"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinHubUrl(config)).isEqualTo("http://zeppelinhub.ltd"); } @@ -81,43 +82,43 @@ public void testGetZeppelinHubWsEndpoint() { System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, testAddr); ZeppelinConfiguration config = new ZeppelinConfiguration(); - ZeppelinHubRepo repository = new ZeppelinHubRepo(config); + ZeppelinHubRepo repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("ws://zeppelinhub.ltd:80/async"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "https://zeppelinhub.ltd"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("wss://zeppelinhub.ltd:443/async"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "yolow"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("wss://www.zeppelinhub.com:443/async"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "http://zeppelinhub.ltd:4242"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("ws://zeppelinhub.ltd:4242/async"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "https://www.zeppelinhub.com"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("wss://www.zeppelinhub.com:443/async"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "http://www.zeppelinhub.com"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("ws://www.zeppelinhub.com:80/async"); System.setProperty(ZeppelinHubRepo.ZEPPELIN_CONF_PROP_NAME_SERVER, "https://www.zeppelinhub.com:4242"); config = new ZeppelinConfiguration(); - repository = new ZeppelinHubRepo(config); + repository = new ZeppelinHubRepo(config, AuthenticationInfo.ANONYMOUS_AUTHENTICATION_INFO); assertThat(repository.getZeppelinhubWebsocketUri(config)).isEqualTo("wss://www.zeppelinhub.com:4242/async"); }