mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
[ZEPPELIN-2699] Helium REST API bug-fixes. Also updated documentation
This commit is contained in:
parent
3dd25c24e4
commit
5d1792180e
7 changed files with 537 additions and 128 deletions
|
|
@ -32,7 +32,7 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
|
||||
## Helium REST API List
|
||||
|
||||
### List of all available helium packages
|
||||
### Get all available helium packages
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
|
|
@ -42,7 +42,7 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/all```</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/package```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
|
|
@ -78,43 +78,61 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
},
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"zeppelin-bubblechart": [
|
||||
]
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
### Get all enabled helium packages
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns all enabled helium packages in configured registries.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/enabledPackage```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sample JSON response</td>
|
||||
<td>
|
||||
<pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"message": "",
|
||||
"body": {
|
||||
"zeppelin.clock": [
|
||||
{
|
||||
"registry": "local",
|
||||
"pkg": {
|
||||
"type": "VISUALIZATION",
|
||||
"name": "zeppelin-bubblechart",
|
||||
"description": "Animated bubble chart",
|
||||
"artifact": ".\/..\/helium\/zeppelin-bubble",
|
||||
"icon": "icon"
|
||||
},
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"registry": "local",
|
||||
"pkg": {
|
||||
"type": "VISUALIZATION",
|
||||
"name": "zeppelin-bubblechart",
|
||||
"description": "Animated bubble chart",
|
||||
"artifact": "zeppelin-bubblechart@0.0.2",
|
||||
"type": "APPLICATION",
|
||||
"name": "zeppelin.clock",
|
||||
"description": "Clock (example)",
|
||||
"artifact": "zeppelin-examples\/zeppelin-example-clock\/target\/zeppelin-example-clock-0.7.0-SNAPSHOT.jar",
|
||||
"className": "org.apache.zeppelin.example.app.clock.Clock",
|
||||
"resources": [
|
||||
[
|
||||
":java.util.Date"
|
||||
]
|
||||
],
|
||||
"icon": "icon"
|
||||
},
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"zeppelin\_horizontalbar": [
|
||||
{
|
||||
"registry": "local",
|
||||
"pkg": {
|
||||
"type": "VISUALIZATION",
|
||||
"name": "zeppelin_horizontalbar",
|
||||
"description": "Horizontal Bar chart (example)",
|
||||
"artifact": ".\/zeppelin-examples\/zeppelin-example-horizontalbar",
|
||||
"icon": "icon"
|
||||
},
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -122,15 +140,70 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
### Suggest Helium application
|
||||
|
||||
### Get single helium package
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns suggested helium application for the paragraph.</td>
|
||||
<td>This ```GET``` method returns specified helium package information</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/package/[Package Name]```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sample JSON response</td>
|
||||
<td>
|
||||
<pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"message": "",
|
||||
"body": {
|
||||
"zeppelin.clock": [
|
||||
{
|
||||
"registry": "local",
|
||||
"pkg": {
|
||||
"type": "APPLICATION",
|
||||
"name": "zeppelin.clock",
|
||||
"description": "Clock (example)",
|
||||
"artifact": "zeppelin-examples\/zeppelin-example-clock\/target\/zeppelin-example-clock-0.7.0-SNAPSHOT.jar",
|
||||
"className": "org.apache.zeppelin.example.app.clock.Clock",
|
||||
"resources": [
|
||||
[
|
||||
":java.util.Date"
|
||||
]
|
||||
],
|
||||
"icon": "icon"
|
||||
},
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
### Suggest Helium package on a paragraph
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns suggested helium package for the paragraph.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
|
|
@ -180,15 +253,15 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
### Load helium Application on a paragraph
|
||||
|
||||
### Load Helium package on a paragraph
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns a helium Application id on success.</td>
|
||||
<td>This ```POST``` method loads helium package to target paragraph.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
|
|
@ -201,8 +274,8 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
<tr>
|
||||
<td>Fail code</td>
|
||||
<td>
|
||||
404 on note or paragraph not exists <br/>
|
||||
500 for any other errors
|
||||
404 on note or paragraph not exists <br />
|
||||
500
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -218,19 +291,19 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Load bundled visualization script
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns bundled helium visualization javascript. When refresh=true (optional) is provided, Zeppelin rebuild bundle. otherwise, provided from cache</td>
|
||||
<td>This ```GET``` method returns bundled helium visualization javascript. When refresh=true (optional) is provided, Zeppelin rebuilds bundle. Otherwise, it's provided from cache</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/visualizations/load[?refresh=true]```</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/bundle/load/[Package Name][?refresh=true]```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
|
|
@ -243,8 +316,8 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Enable package
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
|
|
@ -281,8 +354,8 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Disable package
|
||||
|
||||
<table class="table-configuration">
|
||||
|
|
@ -310,7 +383,7 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<br/>
|
||||
|
||||
### Get visualization display order
|
||||
|
||||
|
|
@ -322,7 +395,7 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/visualizationOrder```</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/order/visualization```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
|
|
@ -339,9 +412,7 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<br />
|
||||
<br/>
|
||||
|
||||
### Set visualization display order
|
||||
|
||||
|
|
@ -353,7 +424,7 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/visualizationOrder```</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/order/visualization```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
|
|
@ -375,4 +446,98 @@ zeppelin-examples/zeppelin-example-clock/target/zeppelin-example-clock-0.7.0-SNA
|
|||
<code>{"status":"OK"}</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
### Get configuration for all Helium packages
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns configuration for all Helium packages</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/config```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
### Get configuration for specific package
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns configuration for the specified package name and artifact</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/config/[Package Name]/[Artifact]```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
### Set configuration for specific package
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method updates configuration for specified package name and artifact</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/config/[Package Name]/[Artifact]```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
### Get Spell configuration for single package
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns specified package Spell configuration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/helium/spell/config/[Package Name]```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
|
@ -51,32 +51,37 @@ public class HeliumRestApi {
|
|||
private Notebook notebook;
|
||||
private Gson gson = new Gson();
|
||||
|
||||
public HeliumRestApi() {
|
||||
}
|
||||
|
||||
public HeliumRestApi(Helium helium, Notebook notebook) {
|
||||
this.helium = helium;
|
||||
this.notebook = notebook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all package infos
|
||||
* Get all packages info
|
||||
*/
|
||||
@GET
|
||||
@Path("package")
|
||||
public Response getAllPackageInfo() {
|
||||
return new JsonResponse(
|
||||
Response.Status.OK, "", helium.getAllPackageInfo()).build();
|
||||
try {
|
||||
return new JsonResponse<>(Response.Status.OK, "", helium.getAllPackageInfo()).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all enabled package infos
|
||||
* Get all enabled packages info
|
||||
*/
|
||||
@GET
|
||||
@Path("enabledPackage")
|
||||
public Response getAllEnabledPackageInfo() {
|
||||
return new JsonResponse(
|
||||
Response.Status.OK, "", helium.getAllEnabledPackages()).build();
|
||||
try {
|
||||
return new JsonResponse<>(Response.Status.OK, "", helium.getAllEnabledPackages()).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,7 +97,7 @@ public class HeliumRestApi {
|
|||
}
|
||||
|
||||
try {
|
||||
return new JsonResponse(
|
||||
return new JsonResponse<>(
|
||||
Response.Status.OK, "", helium.getSinglePackageInfo(packageName)).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
|
|
@ -114,13 +119,19 @@ public class HeliumRestApi {
|
|||
return new JsonResponse(Response.Status.NOT_FOUND, "Paragraph " + paragraphId + " not found")
|
||||
.build();
|
||||
}
|
||||
try {
|
||||
return new JsonResponse<>(Response.Status.OK, "", helium.suggestApp(paragraph)).build();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
|
||||
return new JsonResponse(Response.Status.OK, "", helium.suggestApp(paragraph)).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("load/{noteId}/{paragraphId}")
|
||||
public Response suggest(@PathParam("noteId") String noteId,
|
||||
public Response load(@PathParam("noteId") String noteId,
|
||||
@PathParam("paragraphId") String paragraphId,
|
||||
String heliumPackage) {
|
||||
|
||||
|
|
@ -135,9 +146,14 @@ public class HeliumRestApi {
|
|||
.build();
|
||||
}
|
||||
HeliumPackage pkg = HeliumPackage.fromJson(heliumPackage);
|
||||
|
||||
String appId = helium.getApplicationFactory().loadAndRun(pkg, paragraph);
|
||||
return new JsonResponse(Response.Status.OK, "", appId).build();
|
||||
try {
|
||||
return new JsonResponse<>(Response.Status.OK, "",
|
||||
helium.getApplicationFactory().loadAndRun(pkg, paragraph)).build();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
|
|
@ -190,8 +206,12 @@ public class HeliumRestApi {
|
|||
public Response enablePackage(@PathParam("packageName") String packageName,
|
||||
String artifact) {
|
||||
try {
|
||||
helium.enable(packageName, artifact);
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
if (helium.enable(packageName, artifact)) {
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
}
|
||||
else {
|
||||
return new JsonResponse(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
|
|
@ -202,8 +222,12 @@ public class HeliumRestApi {
|
|||
@Path("disable/{packageName}")
|
||||
public Response disablePackage(@PathParam("packageName") String packageName) {
|
||||
try {
|
||||
helium.disable(packageName);
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
if (helium.disable(packageName)) {
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
}
|
||||
else {
|
||||
return new JsonResponse(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
|
|
@ -227,7 +251,7 @@ public class HeliumRestApi {
|
|||
"Failed to find enabled package for " + packageName).build();
|
||||
}
|
||||
|
||||
return new JsonResponse(Response.Status.OK, config).build();
|
||||
return new JsonResponse<>(Response.Status.OK, config).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
|
|
@ -239,7 +263,7 @@ public class HeliumRestApi {
|
|||
public Response getAllPackageConfigs() {
|
||||
try {
|
||||
Map<String, Map<String, Object>> config = helium.getAllPackageConfig();
|
||||
return new JsonResponse(Response.Status.OK, config).build();
|
||||
return new JsonResponse<>(Response.Status.OK, config).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
|
|
@ -265,7 +289,7 @@ public class HeliumRestApi {
|
|||
"Failed to find package for " + artifact).build();
|
||||
}
|
||||
|
||||
return new JsonResponse(Response.Status.OK, config).build();
|
||||
return new JsonResponse<>(Response.Status.OK, config).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
|
|
@ -284,12 +308,11 @@ public class HeliumRestApi {
|
|||
).build();
|
||||
}
|
||||
|
||||
Map<String, Object> packageConfig = null;
|
||||
|
||||
try {
|
||||
packageConfig = gson.fromJson(
|
||||
Map<String, Object> packageConfig = gson.fromJson(
|
||||
rawConfig, new TypeToken<Map<String, Object>>(){}.getType());
|
||||
helium.updatePackageConfig(artifact, packageConfig);
|
||||
return new JsonResponse<>(Response.Status.OK, packageConfig).build();
|
||||
} catch (JsonParseException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.BAD_REQUEST,
|
||||
|
|
@ -298,15 +321,18 @@ public class HeliumRestApi {
|
|||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR,
|
||||
e.getMessage()).build();
|
||||
}
|
||||
|
||||
return new JsonResponse(Response.Status.OK, packageConfig).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("order/visualization")
|
||||
public Response getVisualizationPackageOrder() {
|
||||
List<String> order = helium.getVisualizationPackageOrder();
|
||||
return new JsonResponse(Response.Status.OK, order).build();
|
||||
try {
|
||||
List<String> order = helium.getVisualizationPackageOrder();
|
||||
return new JsonResponse<>(Response.Status.OK, order).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
|
|
@ -314,13 +340,12 @@ public class HeliumRestApi {
|
|||
public Response setVisualizationPackageOrder(String orderedPackageNameList) {
|
||||
List<String> orderedList = gson.fromJson(
|
||||
orderedPackageNameList, new TypeToken<List<String>>(){}.getType());
|
||||
|
||||
try {
|
||||
helium.setVisualizationPackageOrder(orderedList);
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return new JsonResponse(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()).build();
|
||||
}
|
||||
return new JsonResponse(Response.Status.OK).build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* 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.rest;
|
||||
|
||||
import com.google.gson.internal.StringMap;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.zeppelin.helium.*;
|
||||
import org.apache.zeppelin.server.ZeppelinServer;
|
||||
import org.apache.zeppelin.user.AuthenticationInfo;
|
||||
import org.junit.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class HeliumRestApiTest extends AbstractTestRestApi {
|
||||
@BeforeClass
|
||||
public static void init() throws Exception {
|
||||
AbstractTestRestApi.startUp();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void destroy() throws Exception {
|
||||
AbstractTestRestApi.shutDown();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
HeliumTestRegistry registry = new HeliumTestRegistry("r1", "r1");
|
||||
ZeppelinServer.helium.clearConf();
|
||||
ZeppelinServer.helium.addRegistry(registry);
|
||||
|
||||
registry.add(new HeliumPackage(
|
||||
HeliumType.APPLICATION,
|
||||
"name1",
|
||||
"desc1",
|
||||
"artifact1",
|
||||
"className1",
|
||||
new String[][]{},
|
||||
"",
|
||||
""));
|
||||
|
||||
registry.add(new HeliumPackage(
|
||||
HeliumType.APPLICATION,
|
||||
"name2",
|
||||
"desc2",
|
||||
"artifact2",
|
||||
"className2",
|
||||
new String[][]{},
|
||||
"",
|
||||
""));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ZeppelinServer.helium.clearRegistries();
|
||||
ZeppelinServer.helium.clearConf();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllPackageInfo() throws IOException {
|
||||
GetMethod get = httpGet("/helium/package");
|
||||
assertThat(get, isAllowed());
|
||||
Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
Map<String, Set<String>> body = (Map<String, Set<String>>) resp.get("body");
|
||||
|
||||
assertEquals(body.size(), 2);
|
||||
assertTrue(body.containsKey("name1"));
|
||||
assertTrue(body.containsKey("name2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllEnabledPackageInfo() throws IOException {
|
||||
// No enabled packages initially
|
||||
GetMethod get1 = httpGet("/helium/enabledPackage");
|
||||
assertThat(get1, isAllowed());
|
||||
Map<String, Object> resp1 = gson.fromJson(get1.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<StringMap<Object>> body1 = (List<StringMap<Object>>) resp1.get("body");
|
||||
assertEquals(body1.size(), 0);
|
||||
|
||||
// Enable "name1" package
|
||||
ZeppelinServer.helium.enable("name1","artifact1");
|
||||
|
||||
GetMethod get2 = httpGet("/helium/enabledPackage");
|
||||
assertThat(get2, isAllowed());
|
||||
Map<String, Object> resp2 = gson.fromJson(get2.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<StringMap<Object>> body2 = (List<StringMap<Object>>) resp2.get("body");
|
||||
|
||||
assertEquals(body2.size(), 1);
|
||||
StringMap<Object> pkg = (StringMap<Object>) body2.get(0).get("pkg");
|
||||
assertEquals(pkg.get("name"), "name1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSinglePackageInfo() throws IOException {
|
||||
String packageName = "name1";
|
||||
GetMethod get = httpGet("/helium/package/" + packageName);
|
||||
assertThat(get, isAllowed());
|
||||
Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<StringMap<Object>> body = (List<StringMap<Object>>) resp.get("body");
|
||||
|
||||
assertEquals(body.size(), 1);
|
||||
StringMap<Object> pkg = (StringMap<Object>) body.get(0).get("pkg");
|
||||
assertEquals(pkg.get("name"), "name1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllPackageConfigs() throws IOException {
|
||||
GetMethod get = httpGet("/helium/config/");
|
||||
assertThat(get, isAllowed());
|
||||
Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
StringMap<Object> body = (StringMap<Object>) resp.get("body");
|
||||
// ToDo: Apply config with POST command and check update
|
||||
assertEquals(body.size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPackageConfig() throws IOException {
|
||||
String packageName = "name1";
|
||||
String artifact = "artifact1";
|
||||
GetMethod get = httpGet("/helium/config/" + packageName + "/" + artifact);
|
||||
assertThat(get, isAllowed());
|
||||
Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
StringMap<Object> body = (StringMap<Object>) resp.get("body");
|
||||
assertTrue(body.containsKey("confPersisted"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableDisablePackage() throws IOException {
|
||||
String packageName = "name1";
|
||||
PostMethod post1 = httpPost("/helium/enable/" + packageName, "");
|
||||
assertThat(post1, isAllowed());
|
||||
post1.releaseConnection();
|
||||
|
||||
GetMethod get1 = httpGet("/helium/package/" + packageName);
|
||||
Map<String, Object> resp1 = gson.fromJson(get1.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<StringMap<Object>> body1 = (List<StringMap<Object>>) resp1.get("body");
|
||||
assertEquals(body1.get(0).get("enabled"), true);
|
||||
|
||||
PostMethod post2 = httpPost("/helium/disable/" + packageName, "");
|
||||
assertThat(post2, isAllowed());
|
||||
post2.releaseConnection();
|
||||
|
||||
GetMethod get2 = httpGet("/helium/package/" + packageName);
|
||||
Map<String, Object> resp2 = gson.fromJson(get2.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<StringMap<Object>> body2 = (List<StringMap<Object>>) resp2.get("body");
|
||||
assertEquals(body2.get(0).get("enabled"), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVisualizationPackageOrder() throws IOException {
|
||||
GetMethod get1 = httpGet("/helium/order/visualization");
|
||||
assertThat(get1, isAllowed());
|
||||
Map<String, Object> resp1 = gson.fromJson(get1.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<Object> body1 = (List<Object>) resp1.get("body");
|
||||
assertEquals(body1.size(), 0);
|
||||
|
||||
String postRequestJson = "[name2, name1]";
|
||||
PostMethod post = httpPost("/helium/order/visualization", postRequestJson);
|
||||
assertThat(post, isAllowed());
|
||||
post.releaseConnection();
|
||||
|
||||
GetMethod get2 = httpGet("/helium/order/visualization");
|
||||
assertThat(get2, isAllowed());
|
||||
Map<String, Object> resp2 = gson.fromJson(get2.getResponseBodyAsString(),
|
||||
new TypeToken<Map<String, Object>>() { }.getType());
|
||||
List<Object> body2 = (List<Object>) resp2.get("body");
|
||||
assertEquals(body2.size(), 2);
|
||||
assertEquals(body2.get(0), "name2");
|
||||
assertEquals(body2.get(1), "name1");
|
||||
}
|
||||
}
|
||||
|
||||
class HeliumTestRegistry extends HeliumRegistry {
|
||||
private List<HeliumPackage> infos = new LinkedList<>();
|
||||
|
||||
public HeliumTestRegistry(String name, String uri) {
|
||||
super(name, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeliumPackage> getAll() throws IOException {
|
||||
return infos;
|
||||
}
|
||||
|
||||
public void add(HeliumPackage info) {
|
||||
infos.add(info);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ public class Helium {
|
|||
Logger logger = LoggerFactory.getLogger(Helium.class);
|
||||
private List<HeliumRegistry> registry = new LinkedList<>();
|
||||
|
||||
private final HeliumConf heliumConf;
|
||||
private HeliumConf heliumConf;
|
||||
private final String heliumConfPath;
|
||||
private final String registryPaths;
|
||||
private final File registryCacheDir;
|
||||
|
|
@ -49,7 +49,7 @@ public class Helium {
|
|||
private final HeliumBundleFactory bundleFactory;
|
||||
private final HeliumApplicationFactory applicationFactory;
|
||||
|
||||
Map<String, List<HeliumPackageSearchResult>> allPackages;
|
||||
private Map<String, List<HeliumPackageSearchResult>> allPackages;
|
||||
|
||||
public Helium(
|
||||
String heliumConfPath,
|
||||
|
|
@ -77,6 +77,14 @@ public class Helium {
|
|||
}
|
||||
}
|
||||
|
||||
public void clearRegistries() {
|
||||
this.registry.clear();
|
||||
}
|
||||
|
||||
public void clearConf() {
|
||||
this.heliumConf = new HeliumConf();
|
||||
}
|
||||
|
||||
public List<HeliumRegistry> getAllRegistry() {
|
||||
synchronized (this.registry) {
|
||||
List list = new LinkedList<>();
|
||||
|
|
@ -91,10 +99,6 @@ public class Helium {
|
|||
return applicationFactory;
|
||||
}
|
||||
|
||||
public HeliumBundleFactory getBundleFactory() {
|
||||
return bundleFactory;
|
||||
}
|
||||
|
||||
private synchronized HeliumConf loadConf(String path) throws IOException {
|
||||
// add registry
|
||||
if (registryPaths != null && !registryPaths.isEmpty()) {
|
||||
|
|
@ -122,7 +126,7 @@ public class Helium {
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized void save() throws IOException {
|
||||
public synchronized void saveConfig() throws IOException {
|
||||
String jsonString;
|
||||
synchronized (registry) {
|
||||
clearNotExistsPackages();
|
||||
|
|
@ -138,7 +142,7 @@ public class Helium {
|
|||
}
|
||||
|
||||
private void clearNotExistsPackages() {
|
||||
Map<String, List<HeliumPackageSearchResult>> all = getAllPackageInfoWithoutRefresh();
|
||||
Map<String, List<HeliumPackageSearchResult>> all = getAllPackageInfo();
|
||||
|
||||
// clear visualization display order
|
||||
List<String> packageOrder = heliumConf.getBundleDisplayOrder();
|
||||
|
|
@ -187,9 +191,7 @@ public class Helium {
|
|||
!name.equals(packageName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String artifact = enabledPackageInfo.get(name);
|
||||
boolean enabled = (artifact != null && artifact.equals(pkg.getArtifact()));
|
||||
boolean enabled = enabledPackageInfo.containsKey(pkg.getName());
|
||||
|
||||
if (!allPackages.containsKey(name)) {
|
||||
allPackages.put(name, new LinkedList<HeliumPackageSearchResult>());
|
||||
|
|
@ -208,12 +210,10 @@ public class Helium {
|
|||
}
|
||||
|
||||
List<HeliumPackageSearchResult> pkgs = allPackages.get(name);
|
||||
String artifact = enabledPackageInfo.get(name);
|
||||
LinkedList<HeliumPackageSearchResult> newResults =
|
||||
new LinkedList<HeliumPackageSearchResult>();
|
||||
LinkedList<HeliumPackageSearchResult> newResults = new LinkedList<>();
|
||||
|
||||
for (HeliumPackageSearchResult pkg : pkgs) {
|
||||
boolean enabled = (artifact != null && artifact.equals(pkg.getPkg().getArtifact()));
|
||||
boolean enabled = enabledPackageInfo.containsKey(pkg.getPkg().getName());
|
||||
newResults.add(new HeliumPackageSearchResult(pkg.getRegistry(), pkg.getPkg(), enabled));
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ public class Helium {
|
|||
}
|
||||
|
||||
public List<HeliumPackageSearchResult> getAllEnabledPackages() {
|
||||
Map<String, List<HeliumPackageSearchResult>> allPackages = getAllPackageInfoWithoutRefresh();
|
||||
Map<String, List<HeliumPackageSearchResult>> allPackages = getAllPackageInfo();
|
||||
List<HeliumPackageSearchResult> enabledPackages = new ArrayList<>();
|
||||
|
||||
for (List<HeliumPackageSearchResult> versionedPackages : allPackages.values()) {
|
||||
|
|
@ -252,17 +252,16 @@ public class Helium {
|
|||
}
|
||||
|
||||
public List<HeliumPackageSearchResult> getSinglePackageInfo(String packageName) {
|
||||
Map<String, List<HeliumPackageSearchResult>> result = getAllPackageInfo(false, packageName);
|
||||
Map<String, List<HeliumPackageSearchResult>> result = getAllPackageInfo(true, packageName);
|
||||
|
||||
if (!result.containsKey(packageName)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return result.get(packageName);
|
||||
}
|
||||
|
||||
public HeliumPackageSearchResult getEnabledPackageInfo(String packageName) {
|
||||
Map<String, List<HeliumPackageSearchResult>> infos = getAllPackageInfoWithoutRefresh();
|
||||
private HeliumPackageSearchResult getEnabledPackageInfo(String packageName) {
|
||||
Map<String, List<HeliumPackageSearchResult>> infos = getAllPackageInfo();
|
||||
List<HeliumPackageSearchResult> packages = infos.get(packageName);
|
||||
|
||||
for (HeliumPackageSearchResult pkgSearchResult : packages) {
|
||||
|
|
@ -274,10 +273,10 @@ public class Helium {
|
|||
return null;
|
||||
}
|
||||
|
||||
public HeliumPackageSearchResult getPackageInfo(String pkgName, String artifact) {
|
||||
Map<String, List<HeliumPackageSearchResult>> infos = getAllPackageInfo(false, pkgName);
|
||||
private HeliumPackageSearchResult getPackageInfo(String pkgName, String artifact) {
|
||||
Map<String, List<HeliumPackageSearchResult>> infos = getAllPackageInfo(true, pkgName);
|
||||
List<HeliumPackageSearchResult> packages = infos.get(pkgName);
|
||||
if (artifact == null) {
|
||||
if (StringUtils.isBlank(artifact)) {
|
||||
return packages.get(0); /** return the FIRST package */
|
||||
} else {
|
||||
for (HeliumPackageSearchResult pkg : packages) {
|
||||
|
|
@ -286,7 +285,6 @@ public class Helium {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -294,12 +292,12 @@ public class Helium {
|
|||
return bundleFactory.buildPackage(pkg, rebuild, true);
|
||||
}
|
||||
|
||||
public void enable(String name, String artifact) throws IOException {
|
||||
public boolean enable(String name, String artifact) throws IOException {
|
||||
HeliumPackageSearchResult pkgInfo = getPackageInfo(name, artifact);
|
||||
|
||||
// no package found.
|
||||
if (pkgInfo == null) {
|
||||
return;
|
||||
logger.info("Package {} not found", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// if package is bundle, rebuild bundle
|
||||
|
|
@ -317,17 +315,19 @@ public class Helium {
|
|||
}
|
||||
}
|
||||
|
||||
save();
|
||||
saveConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void disable(String name) throws IOException {
|
||||
String artifact = heliumConf.getEnabledPackages().get(name);
|
||||
public boolean disable(String name) throws IOException {
|
||||
String pkg = heliumConf.getEnabledPackages().get(name);
|
||||
|
||||
if (artifact == null) {
|
||||
return;
|
||||
if (pkg == null) {
|
||||
logger.info("Package {} not found", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
HeliumPackageSearchResult pkgInfo = getPackageInfo(name, artifact);
|
||||
HeliumPackageSearchResult pkgInfo = getPackageInfo(name, pkg);
|
||||
|
||||
// set `enable` field
|
||||
heliumConf.disablePackage(name);
|
||||
|
|
@ -337,21 +337,22 @@ public class Helium {
|
|||
currentDisplayOrder.remove(name);
|
||||
}
|
||||
}
|
||||
save();
|
||||
saveConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updatePackageConfig(String artifact, Map<String, Object> pkgConfig)
|
||||
throws IOException {
|
||||
|
||||
heliumConf.updatePackageConfig(artifact, pkgConfig);
|
||||
save();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
public Map<String, Map<String, Object>> getAllPackageConfig() {
|
||||
return heliumConf.getAllPackageConfigs();
|
||||
}
|
||||
|
||||
public Map<String, Object> getPackagePersistedConfig(String artifact) {
|
||||
private Map<String, Object> getPackagePersistedConfig(String artifact) {
|
||||
return heliumConf.getPackagePersistedConfig(artifact);
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +377,7 @@ public class Helium {
|
|||
allResources = ResourcePoolUtils.getAllResources();
|
||||
}
|
||||
|
||||
for (List<HeliumPackageSearchResult> pkgs : getAllPackageInfoWithoutRefresh().values()) {
|
||||
for (List<HeliumPackageSearchResult> pkgs : getAllPackageInfo().values()) {
|
||||
for (HeliumPackageSearchResult pkg : pkgs) {
|
||||
if (pkg.getPkg().getType() == HeliumType.APPLICATION && pkg.isEnabled()) {
|
||||
ResourceSet resources = ApplicationLoader.findRequiredResourceSet(
|
||||
|
|
@ -404,7 +405,7 @@ public class Helium {
|
|||
* @return ordered list of enabled buildBundle package
|
||||
*/
|
||||
public List<HeliumPackage> getBundlePackagesToBundle() {
|
||||
Map<String, List<HeliumPackageSearchResult>> allPackages = getAllPackageInfoWithoutRefresh();
|
||||
Map<String, List<HeliumPackageSearchResult>> allPackages = getAllPackageInfo();
|
||||
List<String> visOrder = heliumConf.getBundleDisplayOrder();
|
||||
|
||||
List<HeliumPackage> orderedBundlePackages = new LinkedList<>();
|
||||
|
|
@ -437,7 +438,7 @@ public class Helium {
|
|||
return orderedBundlePackages;
|
||||
}
|
||||
|
||||
public boolean canBundle(HeliumPackageSearchResult pkgInfo) {
|
||||
private boolean canBundle(HeliumPackageSearchResult pkgInfo) {
|
||||
return (pkgInfo.isEnabled() &&
|
||||
HeliumPackage.isBundleType(pkgInfo.getPkg().getType()));
|
||||
}
|
||||
|
|
@ -453,7 +454,7 @@ public class Helium {
|
|||
public void setVisualizationPackageOrder(List<String> orderedPackageList)
|
||||
throws IOException {
|
||||
heliumConf.setBundleDisplayOrder(orderedPackageList);
|
||||
save();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -494,7 +495,7 @@ public class Helium {
|
|||
return createMixedConfig(configPersisted, configSpec);
|
||||
}
|
||||
|
||||
public static Map<String, Map<String, Object>> createMixedConfig(Map<String, Object> persisted,
|
||||
private static Map<String, Map<String, Object>> createMixedConfig(Map<String, Object> persisted,
|
||||
Map<String, Object> spec) {
|
||||
Map<String, Map<String, Object>> mixed = new HashMap<>();
|
||||
mixed.put("confPersisted", persisted);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ public class HeliumConf implements JsonSerializable {
|
|||
packageConfig.put(artifact,
|
||||
Collections.synchronizedMap(new HashMap<String, Object>()));
|
||||
}
|
||||
|
||||
packageConfig.put(artifact, newConfig);
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +90,7 @@ public class HeliumConf implements JsonSerializable {
|
|||
|
||||
public List<String> getBundleDisplayOrder() {
|
||||
if (bundleDisplayOrder == null) {
|
||||
return new LinkedList<String>();
|
||||
return new LinkedList<>();
|
||||
} else {
|
||||
return bundleDisplayOrder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class HeliumTest {
|
|||
assertFalse(heliumConf.exists());
|
||||
|
||||
// when
|
||||
helium.save();
|
||||
helium.saveConfig();
|
||||
|
||||
// then
|
||||
assertTrue(heliumConf.exists());
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
|
||||
public class HeliumTestRegistry extends HeliumRegistry {
|
||||
List<HeliumPackage> infos = new LinkedList<>();
|
||||
private List<HeliumPackage> infos = new LinkedList<>();
|
||||
|
||||
public HeliumTestRegistry(String name, String uri) {
|
||||
super(name, uri);
|
||||
|
|
|
|||
Loading…
Reference in a new issue