Skip to content

Commit

Permalink
[apache#960][part-3] feat(dashboard): Provides a start-stop script fo…
Browse files Browse the repository at this point in the history
…r the dashboard. (apache#1056)

### What changes were proposed in this pull request?
Provides a start-stop script for the dashboard.

### Why are the changes needed?

Fix: apache#960

### Does this PR introduce any user-facing change?
Start and close the dashboard module using shell scripts.

### How was this patch tested?
UT.
  • Loading branch information
yl09099 authored Nov 23, 2023
1 parent d72a483 commit 51e02d0
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 18 deletions.
86 changes: 86 additions & 0 deletions bin/start-dashboard.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bash

#
# 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.
#

set -o pipefail
set -o nounset # exit the script if you try to use an uninitialised variable
set -o errexit # exit the script if any statement returns a non-true return value

source "$(dirname "$0")/utils.sh"
load_rss_env

cd "$RSS_HOME"

COORDINATOR_CONF_FILE="${RSS_CONF_DIR}/coordinator.conf"
JAR_DIR="${RSS_HOME}/jars"
LOG_CONF_FILE="${RSS_CONF_DIR}/log4j.properties"
LOG_PATH="${RSS_LOG_DIR}/dashboard.log"
OUT_PATH="${RSS_LOG_DIR}/dashboard.out"

MAIN_CLASS="org.apache.uniffle.dashboard.web.JettyServerFront"

HADOOP_DEPENDENCY="$("$HADOOP_HOME/bin/hadoop" classpath --glob)"

echo "Check process existence"
is_jvm_process_running "$JPS" $MAIN_CLASS

CLASSPATH=""

for file in $(ls ${JAR_DIR}/dashboard/*.jar 2>/dev/null); do
CLASSPATH=$CLASSPATH:$file
done

mkdir -p "${RSS_LOG_DIR}"
mkdir -p "${RSS_PID_DIR}"

CLASSPATH=$CLASSPATH:$HADOOP_CONF_DIR:$HADOOP_DEPENDENCY
JAVA_LIB_PATH="-Djava.library.path=$HADOOP_HOME/lib/native"

echo "class path is $CLASSPATH"

JVM_ARGS=" -server \
-Xmx${XMX_SIZE:-8g} \
-Xms${XMX_SIZE:-8g} \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:ParallelGCThreads=20 \
-XX:ConcGCThreads=5 \
-XX:InitiatingHeapOccupancyPercent=45 \
-XX:+PrintGC \
-XX:+PrintAdaptiveSizePolicy \
-XX:+PrintGCDateStamps \
-XX:+PrintGCTimeStamps \
-XX:+PrintGCDetails \
-Xloggc:${RSS_LOG_DIR}/gc-%t.log"

JAVA11_EXTRA_ARGS=" -XX:+IgnoreUnrecognizedVMOptions \
-Xlog:gc:tags,time,uptime,level"

ARGS=""

if [ -f ${LOG_CONF_FILE} ]; then
ARGS="$ARGS -Dlog4j.configuration=file:${LOG_CONF_FILE} -Dlog.path=${LOG_PATH}"
else
echo "Exit with error: ${LOG_CONF_FILE} file doesn't exist."
exit 1
fi

$RUNNER $ARGS $JVM_ARGS $JAVA11_EXTRA_ARGS -cp $CLASSPATH $MAIN_CLASS --conf "$COORDINATOR_CONF_FILE" $@ &> $OUT_PATH &

get_pid_file_name uniffle-dashboard
echo $! >${RSS_PID_DIR}/${pid_file}
28 changes: 28 additions & 0 deletions bin/stop-dashboard.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

#
# 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.
#
#

set -o pipefail
set -o nounset # exit the script if you try to use an uninitialised variable
set -o errexit # exit the script if any statement returns a non-true return value

source "$(dirname "$0")/utils.sh"
load_rss_env

common_shutdown "uniffle-dashboard" "${RSS_PID_DIR}"
7 changes: 7 additions & 0 deletions build_distribution.sh
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ echo "copy $COORDINATOR_JAR to ${COORDINATOR_JAR_DIR}"
cp $COORDINATOR_JAR ${COORDINATOR_JAR_DIR}
cp "${RSS_HOME}"/coordinator/target/jars/* ${COORDINATOR_JAR_DIR}

DASHBOARD_JAR_DIR="${DISTDIR}/jars/dashboard"
mkdir -p $DASHBOARD_JAR_DIR
DASHBOARD_JAR="${RSS_HOME}/dashboard/target/dashboard-${VERSION}.jar"
echo "copy $DASHBOARD_JAR to ${DASHBOARD_JAR_DIR}"
cp $DASHBOARD_JAR $DASHBOARD_JAR_DIR
cp "${RSS_HOME}"/dashboard/target/jars/* ${DASHBOARD_JAR_DIR}

CLI_JAR_DIR="${DISTDIR}/jars/cli"
mkdir -p $CLI_JAR_DIR
CLI_JAR="${RSS_HOME}/cli/target/cli-${VERSION}.jar"
Expand Down
4 changes: 4 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-proxy</artifactId>
</dependency>
<dependency>
<groupId>org.apache.hbase.thirdparty</groupId>
<artifactId>hbase-shaded-jersey</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.proxy.ProxyServlet;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.thread.ExecutorThreadPool;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
Expand All @@ -40,6 +44,7 @@
import org.apache.uniffle.common.util.ExitUtils;
import org.apache.uniffle.common.util.ThreadUtils;
import org.apache.uniffle.dashboard.web.config.DashboardConf;
import org.apache.uniffle.dashboard.web.proxy.WebProxyServlet;

public class JettyServerFront {

Expand Down Expand Up @@ -83,14 +88,29 @@ private void initialization() {
}

private void setRootServletHandler() {
final ContextHandler contextHandler = new ContextHandler("/");
HandlerList handlers = new HandlerList();
ResourceHandler resourceHandler = addResourceHandler();
String coordinatorWebAddress = conf.getString(DashboardConf.COORDINATOR_WEB_ADDRESS);
ServletContextHandler servletContextHandler = addProxyHandler(coordinatorWebAddress);
handlers.setHandlers(new Handler[] {resourceHandler, servletContextHandler});
server.setHandler(handlers);
}

private static ResourceHandler addResourceHandler() {
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setDirectoriesListed(true);
resourceHandler.setBaseResource(
Resource.newResource(JettyServerFront.class.getClassLoader().getResource("static")));
resourceHandler.setWelcomeFiles(new String[] {"index.html"});
contextHandler.setHandler(resourceHandler);
server.setHandler(contextHandler);
return resourceHandler;
}

private static ServletContextHandler addProxyHandler(String coordinatorWebAddress) {
ProxyServlet proxyServlet = new WebProxyServlet(coordinatorWebAddress);
ServletHolder holder = new ServletHolder(proxyServlet);
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.addServlet(holder, "/api/*");
return contextHandler;
}

private void addHttpConnector(int port, HttpConfiguration httpConfig, long idleTimeout) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public class DashboardConf extends RssBaseConf {
.defaultValue(19988)
.withDescription("http server http port");

public static final ConfigOption<String> COORDINATOR_WEB_ADDRESS =
ConfigOptions.key("coordinator.web.address")
.stringType()
.noDefaultValue()
.withDescription("Coordinator jetty port request address");

public static final ConfigOption<Long> DASHBOARD_STOP_TIMEOUT =
ConfigOptions.key("rss.dashboard.stop.timeout")
.longType()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.uniffle.dashboard.web.proxy;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.proxy.ProxyServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WebProxyServlet extends ProxyServlet {

private String targetAddress;

private static final Logger LOG = LoggerFactory.getLogger(WebProxyServlet.class);

public WebProxyServlet(String targetAddress) {
this.targetAddress = targetAddress;
}

@Override
protected String rewriteTarget(HttpServletRequest clientRequest) {
if (!validateDestination(clientRequest.getServerName(), clientRequest.getServerPort())) {
return null;
}
StringBuilder target = new StringBuilder();

if (targetAddress.endsWith("/")) {
targetAddress = targetAddress.substring(0, targetAddress.length() - 1);
}
target.append(targetAddress).append("/api").append(clientRequest.getPathInfo());
String query = clientRequest.getQueryString();
if (query != null) {
target.append("?").append(query);
}
return target.toString();
}

@Override
protected void onProxyRewriteFailed(
HttpServletRequest clientRequest, HttpServletResponse clientResponse) {}

@Override
protected void onProxyResponseFailure(
HttpServletRequest clientRequest,
HttpServletResponse proxyResponse,
Response serverResponse,
Throwable failure) {}

@Override
protected String filterServerResponseHeader(
HttpServletRequest clientRequest,
Response serverResponse,
String headerName,
String headerValue) {
return null;
}

@Override
protected void addXForwardedHeaders(HttpServletRequest clientRequest, Request proxyRequest) {}
}
4 changes: 2 additions & 2 deletions dashboard/src/main/webapp/src/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ export function getAppTotal(params){

// Create an interface for the app basic information list
export function getApplicationInfoList(params){
return http.get('/app/appinfos', params,{})
return http.get('/app/appInfos', params,{})
}

// Create an interface for the number of apps for a user
export function getTotalForUser(params){
return http.get('/app/usertotal', params,{})
return http.get('/app/userTotal', params,{})
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export default {

async function getTotalForUserPage() {
const res = await getTotalForUser();
console.log(res)
pageData.userAppCount = res.data.data
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
</div>
</el-collapse-item>
<el-collapse-item title="Coordinator Properties" name="2">
<el-table :data="pageData.tableData" style="width: 100%">
<el-table :data="pageData.tableData" stripe style="width: 100%">
<el-table-column prop="argumentKey" label="Name" min-width="380"/>
<el-table-column prop="argumentValue" label="Value" min-width="380"/>
</el-table>
Expand All @@ -96,11 +96,11 @@ export default {
);
async function getCoordinatorServerConfPage() {
const res = await getCoordinatorConf();
pageData.serverInfo = res.data.data
pageData.tableData = res.data.data
}
async function getCoorServerInfo() {
const res = await getCoordinatorServerInfo();
pageData.tableData = res.data.data
pageData.serverInfo = res.data.data
}
onMounted(() => {
getCoordinatorServerConfPage();
Expand Down
8 changes: 0 additions & 8 deletions dashboard/src/main/webapp/vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,4 @@
*/

module.exports ={
devServer:{
proxy:{
'/api':{
target:'http://localhost:9528',
changeOrigin:true
}
}
}
}
42 changes: 42 additions & 0 deletions docs/dashboard_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
layout: page
displayTitle: Dashboard Guide
title: Dashboard Guide
description: Dashboard Guide
license: |
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.
---
# Dashboard Guide

## Summary
This document explains how to install and start Uniffle's dashboard.

### Configure related parameters
In $RSS_HOME/conf directory, configure the dashboard data request port and front-end access port in the coordinator
``` shell
## Front-end access port
rss.dashboard.http.port 19997
## The dashboard request data port, which is the Coordinator's HTTP port
## coordinator.hostname is the hostname or IP address of a Coordinator
coordinator.web.address http://coordinator.hostname:19998/
```

### Start the dashboard process
In the $RSS_HOME/bin directory, start with a script.
``` shell
## Start dashboard
sh start-dashboard.sh

## Close dashboard
sh stop-dashboard.sh
Loading

0 comments on commit 51e02d0

Please sign in to comment.