mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
fixed issue #2099 , support remote config poll
This commit is contained in:
@@ -8,9 +8,7 @@
|
||||
<version>1.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>canal-admin-server</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.otter</groupId>
|
||||
@@ -199,6 +197,39 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>application.yml</exclude>
|
||||
<exclude>canal_manager.sql</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<attach>false</attach>
|
||||
<descriptors>
|
||||
<descriptor>${basedir}/src/main/assembly/release.xml</descriptor>
|
||||
</descriptors>
|
||||
<finalName>canal-admin-${project.version}</finalName>
|
||||
<outputDirectory>${project.basedir}/../../target</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
41
canal-admin/canal-admin-server/src/main/assembly/release.xml
Normal file
41
canal-admin/canal-admin-server/src/main/assembly/release.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
<id>dist</id>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>.</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>README*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>./src/main/bin</directory>
|
||||
<outputDirectory>bin</outputDirectory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<fileMode>0755</fileMode>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>./src/main/resources</directory>
|
||||
<outputDirectory>/conf</outputDirectory>
|
||||
<includes>
|
||||
<include>application.yml</include>
|
||||
<include>canal_manager.sql</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>./target</directory>
|
||||
<outputDirectory>/lib</outputDirectory>
|
||||
<includes>
|
||||
<include>canal-admin-*.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
5
canal-admin/canal-admin-server/src/main/bin/restart.sh
Normal file
5
canal-admin/canal-admin-server/src/main/bin/restart.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
sh stop.sh
|
||||
|
||||
sh startup.sh
|
||||
22
canal-admin/canal-admin-server/src/main/bin/startup.bat
Executable file
22
canal-admin/canal-admin-server/src/main/bin/startup.bat
Executable file
@@ -0,0 +1,22 @@
|
||||
@echo off
|
||||
@if not "%ECHO%" == "" echo %ECHO%
|
||||
@if "%OS%" == "Windows_NT" setlocal
|
||||
|
||||
set ENV_PATH=.\
|
||||
if "%OS%" == "Windows_NT" set ENV_PATH=%~dp0%
|
||||
|
||||
set conf_dir=%ENV_PATH%\..\conf
|
||||
|
||||
set CLASSPATH=%conf_dir%
|
||||
set CLASSPATH=%conf_dir%\..\lib\*;%CLASSPATH%
|
||||
|
||||
set JAVA_MEM_OPTS= -Xms128m -Xmx512m
|
||||
set JAVA_OPTS_EXT= -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dapplication.codeset=UTF-8 -Dfile.encoding=UTF-8
|
||||
set ADAPTER_OPTS= -DappName=canal-admin
|
||||
|
||||
set JAVA_OPTS= %JAVA_MEM_OPTS% %JAVA_OPTS_EXT% %ADAPTER_OPTS%
|
||||
|
||||
set CMD_STR= java %JAVA_OPTS% -classpath "%CLASSPATH%" com.alibaba.otter.canal.admin.CanalAdminApplication
|
||||
echo start cmd : %CMD_STR%
|
||||
|
||||
java %JAVA_OPTS% -classpath "%CLASSPATH%" com.alibaba.otter.canal.admin.CanalAdminApplication
|
||||
84
canal-admin/canal-admin-server/src/main/bin/startup.sh
Normal file
84
canal-admin/canal-admin-server/src/main/bin/startup.sh
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
|
||||
current_path=`pwd`
|
||||
case "`uname`" in
|
||||
Linux)
|
||||
bin_abs_path=$(readlink -f $(dirname $0))
|
||||
;;
|
||||
*)
|
||||
bin_abs_path=`cd $(dirname $0); pwd`
|
||||
;;
|
||||
esac
|
||||
base=${bin_abs_path}/..
|
||||
export LANG=en_US.UTF-8
|
||||
export BASE=$base
|
||||
|
||||
if [ -f $base/bin/adapter.pid ] ; then
|
||||
echo "found adapter.pid , Please run stop.sh first ,then startup.sh" 2>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d $base/logs ] ; then
|
||||
mkdir -p $base/logs
|
||||
fi
|
||||
|
||||
## set java path
|
||||
if [ -z "$JAVA" ] ; then
|
||||
JAVA=$(which java)
|
||||
fi
|
||||
|
||||
ALIBABA_JAVA="/usr/alibaba/java/bin/java"
|
||||
TAOBAO_JAVA="/opt/taobao/java/bin/java"
|
||||
if [ -z "$JAVA" ]; then
|
||||
if [ -f $ALIBABA_JAVA ] ; then
|
||||
JAVA=$ALIBABA_JAVA
|
||||
elif [ -f $TAOBAO_JAVA ] ; then
|
||||
JAVA=$TAOBAO_JAVA
|
||||
else
|
||||
echo "Cannot find a Java JDK. Please set either set JAVA or put java (>=1.5) in your PATH." 2>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$#"
|
||||
in
|
||||
0 )
|
||||
;;
|
||||
2 )
|
||||
if [ "$1" = "debug" ]; then
|
||||
DEBUG_PORT=$2
|
||||
DEBUG_SUSPEND="n"
|
||||
JAVA_DEBUG_OPT="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=$DEBUG_SUSPEND"
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
echo "THE PARAMETERS MUST BE TWO OR LESS.PLEASE CHECK AGAIN."
|
||||
exit;;
|
||||
esac
|
||||
|
||||
str=`file -L $JAVA | grep 64-bit`
|
||||
if [ -n "$str" ]; then
|
||||
JAVA_OPTS="-server -Xms2048m -Xmx3072m"
|
||||
else
|
||||
JAVA_OPTS="-server -Xms1024m -Xmx1024m"
|
||||
fi
|
||||
|
||||
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=250 -XX:+UseGCOverheadLimit -XX:+ExplicitGCInvokesConcurrent -XX:+PrintAdaptiveSizePolicy -XX:+PrintTenuringDistribution"
|
||||
JAVA_OPTS=" $JAVA_OPTS -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8"
|
||||
CANAL_OPTS="-DappName=canal-admin"
|
||||
|
||||
for i in $base/lib/*;
|
||||
do CLASSPATH=$i:"$CLASSPATH";
|
||||
done
|
||||
|
||||
CLASSPATH="$base/conf:$CLASSPATH";
|
||||
|
||||
echo "cd to $bin_abs_path for workaround relative path"
|
||||
cd $bin_abs_path
|
||||
|
||||
echo CLASSPATH :$CLASSPATH
|
||||
$JAVA $JAVA_OPTS $JAVA_DEBUG_OPT $CANAL_OPTS -classpath .:$CLASSPATH com.alibaba.otter.canal.admin.CanalAdminApplication 1>>/dev/null 2>&1 &
|
||||
echo $! > $base/bin/admin.pid
|
||||
|
||||
echo "cd to $current_path for continue"
|
||||
cd $current_path
|
||||
65
canal-admin/canal-admin-server/src/main/bin/stop.sh
Normal file
65
canal-admin/canal-admin-server/src/main/bin/stop.sh
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
cygwin=false;
|
||||
linux=false;
|
||||
case "`uname`" in
|
||||
CYGWIN*)
|
||||
cygwin=true
|
||||
;;
|
||||
Linux*)
|
||||
linux=true
|
||||
;;
|
||||
esac
|
||||
|
||||
get_pid() {
|
||||
STR=$1
|
||||
PID=$2
|
||||
if $cygwin; then
|
||||
JAVA_CMD="$JAVA_HOME\bin\java"
|
||||
JAVA_CMD=`cygpath --path --unix $JAVA_CMD`
|
||||
JAVA_PID=`ps |grep $JAVA_CMD |awk '{print $1}'`
|
||||
else
|
||||
if $linux; then
|
||||
if [ ! -z "$PID" ]; then
|
||||
JAVA_PID=`ps -C java -f --width 1000|grep "$STR"|grep "$PID"|grep -v grep|awk '{print $2}'`
|
||||
else
|
||||
JAVA_PID=`ps -C java -f --width 1000|grep "$STR"|grep -v grep|awk '{print $2}'`
|
||||
fi
|
||||
else
|
||||
if [ ! -z "$PID" ]; then
|
||||
JAVA_PID=`ps aux |grep "$STR"|grep "$PID"|grep -v grep|awk '{print $2}'`
|
||||
else
|
||||
JAVA_PID=`ps aux |grep "$STR"|grep -v grep|awk '{print $2}'`
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo $JAVA_PID;
|
||||
}
|
||||
|
||||
base=`dirname $0`/..
|
||||
pidfile=$base/bin/admin.pid
|
||||
if [ ! -f "$pidfile" ];then
|
||||
echo "canal-admin is not running. exists"
|
||||
exit
|
||||
fi
|
||||
|
||||
pid=`cat $pidfile`
|
||||
if [ "$pid" == "" ] ; then
|
||||
pid=`get_pid "appName=canal-admin"`
|
||||
fi
|
||||
|
||||
echo -e "`hostname`: stopping canal $pid ... "
|
||||
kill $pid
|
||||
|
||||
LOOPS=0
|
||||
while (true);
|
||||
do
|
||||
gpid=`get_pid "appName=canal-admin" "$pid"`
|
||||
if [ "$gpid" == "" ] ; then
|
||||
echo "Oook! cost:$LOOPS"
|
||||
`rm $pidfile`
|
||||
break;
|
||||
fi
|
||||
let LOOPS=LOOPS+1
|
||||
sleep 1
|
||||
done
|
||||
@@ -74,8 +74,8 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
httpServletResponse.setContentType("application/json;charset=UTF-8");
|
||||
PrintWriter out = httpServletResponse.getWriter();
|
||||
out.print(json);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -84,6 +84,7 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
}
|
||||
})
|
||||
.addPathPatterns("/api/**")
|
||||
.excludePathPatterns("/api/**/config/**")
|
||||
.excludePathPatterns("/api/**/user/login")
|
||||
.excludePathPatterns("/api/**/user/logout")
|
||||
.excludePathPatterns("/api/**/user/info");
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package com.alibaba.otter.canal.admin.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.otter.canal.admin.model.BaseModel;
|
||||
import com.alibaba.otter.canal.admin.model.CanalConfig;
|
||||
@@ -31,17 +36,6 @@ public class CanalConfigController {
|
||||
return BaseModel.getInstance(canalConfigService.getCanalConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息摘要(无配置内容)
|
||||
*
|
||||
* @param env 环境变量
|
||||
* @return 配置信息摘要
|
||||
*/
|
||||
@GetMapping(value = "/config/summary")
|
||||
public BaseModel<CanalConfig> canalConfigSummary(@PathVariable String env) {
|
||||
return BaseModel.getInstance(canalConfigService.getCanalConfigSummary());
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改配置
|
||||
*
|
||||
@@ -54,4 +48,5 @@ public class CanalConfigController {
|
||||
canalConfigService.updateContent(canalConfig);
|
||||
return BaseModel.getInstance("success");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.alibaba.otter.canal.admin.controller;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.otter.canal.admin.model.BaseModel;
|
||||
import com.alibaba.otter.canal.admin.model.CanalConfig;
|
||||
import com.alibaba.otter.canal.admin.model.CanalInstanceConfig;
|
||||
import com.alibaba.otter.canal.admin.service.CanalConfigService;
|
||||
import com.alibaba.otter.canal.admin.service.CanalInstanceService;
|
||||
import com.alibaba.otter.canal.protocol.SecurityUtil;
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
/**
|
||||
* Canal Instance配置管理控制层
|
||||
*
|
||||
* @author rewerma 2019-07-13 下午05:12:16
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/{env}/config")
|
||||
public class PollConfigController {
|
||||
|
||||
private static final byte[] seeds = "canal is best!".getBytes();
|
||||
|
||||
@Autowired
|
||||
CanalInstanceService canalInstanceConfigService;
|
||||
|
||||
@Autowired
|
||||
CanalConfigService canalConfigService;
|
||||
|
||||
@Value(value = "${canal.adminUser}")
|
||||
String user;
|
||||
|
||||
@Value(value = "${canal.adminPasswd}")
|
||||
String passwd;
|
||||
|
||||
/**
|
||||
* 获取server全局配置
|
||||
*/
|
||||
@GetMapping(value = "/server_poll")
|
||||
public BaseModel<CanalConfig> canalConfigPoll(@RequestHeader String user, @RequestHeader String passwd,
|
||||
@PathVariable String env, @RequestParam String md5) {
|
||||
if (!auth(user, passwd)) {
|
||||
throw new RuntimeException("auth :" + user + " is failed");
|
||||
}
|
||||
|
||||
CanalConfig config = canalConfigService.getCanalConfig();
|
||||
if (StringUtils.isEmpty(md5)) {
|
||||
return BaseModel.getInstance(config);
|
||||
} else {
|
||||
|
||||
try {
|
||||
String newMd5 = SecurityUtil.md5String(config.getContent());
|
||||
if (StringUtils.equals(md5, newMd5)) {
|
||||
config.setContent(null);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
}
|
||||
|
||||
return BaseModel.getInstance(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个instance的配置
|
||||
*/
|
||||
@GetMapping(value = "/instance_poll/{destination}")
|
||||
public BaseModel<CanalInstanceConfig> instanceConfigPoll(@RequestHeader String user, @RequestHeader String passwd,
|
||||
@PathVariable String env,
|
||||
@PathVariable String destination, @RequestParam String md5) {
|
||||
if (!auth(user, passwd)) {
|
||||
throw new RuntimeException("auth :" + user + " is failed");
|
||||
}
|
||||
|
||||
CanalInstanceConfig config = canalInstanceConfigService.findOne(destination);
|
||||
if (StringUtils.isEmpty(md5)) {
|
||||
return BaseModel.getInstance(config);
|
||||
} else {
|
||||
try {
|
||||
String newMd5 = SecurityUtil.md5String(config.getContent());
|
||||
if (StringUtils.equals(md5, newMd5)) {
|
||||
config.setContent(null);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
}
|
||||
|
||||
return BaseModel.getInstance(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对应server(ip+port)所需要运行的instance列表
|
||||
*/
|
||||
@GetMapping(value = "/instances_poll")
|
||||
public BaseModel<CanalInstanceConfig> instancesPoll(@RequestHeader String user, @RequestHeader String passwd,
|
||||
@PathVariable String env, @RequestParam String ip,
|
||||
@RequestParam String port, @RequestParam String md5) {
|
||||
if (!auth(user, passwd)) {
|
||||
throw new RuntimeException("auth :" + user + " is failed");
|
||||
}
|
||||
|
||||
CanalInstanceConfig canalInstanceConfig = new CanalInstanceConfig();
|
||||
List<CanalInstanceConfig> configs = canalInstanceConfigService.findList(canalInstanceConfig);
|
||||
List<String> instances = configs.stream().map(config -> config.getName()).collect(Collectors.toList());
|
||||
String data = Joiner.on(',').join(instances);
|
||||
canalInstanceConfig.setContent(data);
|
||||
if (StringUtils.isEmpty(md5)) {
|
||||
return BaseModel.getInstance(canalInstanceConfig);
|
||||
} else {
|
||||
try {
|
||||
String newMd5 = SecurityUtil.md5String(canalInstanceConfig.getContent());
|
||||
if (StringUtils.equals(md5, newMd5)) {
|
||||
canalInstanceConfig.setContent(null);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
}
|
||||
|
||||
return BaseModel.getInstance(canalInstanceConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean auth(String user, String passwd) {
|
||||
// 如果user/passwd密码为空,则任何用户账户都能登录
|
||||
if ((StringUtils.isEmpty(this.user) || StringUtils.equals(this.user, user))) {
|
||||
if (StringUtils.isEmpty(this.passwd)) {
|
||||
return true;
|
||||
} else if (StringUtils.isEmpty(passwd)) {
|
||||
// 如果server密码有配置,客户端密码为空,则拒绝
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// manager这里保存了原始密码,反过来和canal发送过来的进行校验
|
||||
byte[] passForClient = SecurityUtil.scramble411(this.passwd.getBytes(), seeds);
|
||||
return SecurityUtil.scrambleServerAuth(passForClient, SecurityUtil.hexStr2Bytes(passwd), seeds);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ public class CanalConfig extends Model {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String content;
|
||||
private String status;
|
||||
private Date modifiedTime;
|
||||
|
||||
public Long getId() {
|
||||
@@ -66,4 +67,13 @@ public class CanalConfig extends Model {
|
||||
public void setModifiedTime(Date modifiedTime) {
|
||||
this.modifiedTime = modifiedTime;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.alibaba.otter.canal.admin.model;
|
||||
|
||||
import io.ebean.Finder;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Transient;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Canal实例配置信息实体类
|
||||
@@ -33,6 +34,7 @@ public class CanalInstanceConfig extends Model {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String content;
|
||||
private String status;
|
||||
private Date modifiedTime;
|
||||
|
||||
@Transient
|
||||
@@ -64,6 +66,14 @@ public class CanalInstanceConfig extends Model {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Date getModifiedTime() {
|
||||
return modifiedTime;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.alibaba.otter.canal.admin.model;
|
||||
|
||||
import io.ebean.Finder;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import io.ebean.Finder;
|
||||
|
||||
/**
|
||||
* 节点信息实体类
|
||||
*
|
||||
@@ -35,13 +35,14 @@ public class NodeServer extends Model {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String ip;
|
||||
private Integer port;
|
||||
private Integer port2;
|
||||
private Integer status;
|
||||
private Integer adminPort;
|
||||
private Integer metricPort;
|
||||
private Integer tcpPort;
|
||||
private String status;
|
||||
private Date modifiedTime;
|
||||
|
||||
public void init() {
|
||||
status = -1;
|
||||
status = "-1";
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
@@ -68,27 +69,35 @@ public class NodeServer extends Model {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
public Integer getAdminPort() {
|
||||
return adminPort;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
public void setAdminPort(Integer adminPort) {
|
||||
this.adminPort = adminPort;
|
||||
}
|
||||
|
||||
public Integer getPort2() {
|
||||
return port2;
|
||||
public Integer getMetricPort() {
|
||||
return metricPort;
|
||||
}
|
||||
|
||||
public void setPort2(Integer port2) {
|
||||
this.port2 = port2;
|
||||
public void setMetricPort(Integer metricPort) {
|
||||
this.metricPort = metricPort;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
public Integer getTcpPort() {
|
||||
return tcpPort;
|
||||
}
|
||||
|
||||
public void setTcpPort(Integer tcpPort) {
|
||||
this.tcpPort = tcpPort;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.alibaba.otter.canal.admin.service;
|
||||
|
||||
import com.alibaba.otter.canal.admin.model.CanalInstanceConfig;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.otter.canal.admin.model.CanalInstanceConfig;
|
||||
|
||||
/**
|
||||
* Canal实例配置信息业务层接口
|
||||
*
|
||||
@@ -19,6 +19,8 @@ public interface CanalInstanceService {
|
||||
|
||||
CanalInstanceConfig detail(Long id);
|
||||
|
||||
CanalInstanceConfig findOne(String name);
|
||||
|
||||
void updateContent(CanalInstanceConfig canalInstanceConfig);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
@@ -40,7 +40,7 @@ public class CanalInstanceServiceImpl implements CanalInstanceService {
|
||||
List<NodeServer> nodeServers = NodeServer.find.query().findList();
|
||||
for (NodeServer nodeServer : nodeServers) {
|
||||
String runningInstances = SimpleAdminConnectors.execute(nodeServer.getIp(),
|
||||
nodeServer.getPort(),
|
||||
nodeServer.getAdminPort(),
|
||||
AdminConnector::getRunningInstances);
|
||||
if (runningInstances == null) {
|
||||
continue;
|
||||
@@ -79,6 +79,16 @@ public class CanalInstanceServiceImpl implements CanalInstanceService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CanalInstanceConfig findOne(String name) {
|
||||
CanalInstanceConfig config = CanalInstanceConfig.find.query()
|
||||
.setDisableLazyLoading(true)
|
||||
.where()
|
||||
.eq("name", name)
|
||||
.findOne();
|
||||
return config;
|
||||
}
|
||||
|
||||
public Map<String, String> remoteInstanceLog(Long id, Long nodeId) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
|
||||
@@ -92,7 +102,7 @@ public class CanalInstanceServiceImpl implements CanalInstanceService {
|
||||
}
|
||||
|
||||
String log = SimpleAdminConnectors.execute(nodeServer.getIp(),
|
||||
nodeServer.getPort(),
|
||||
nodeServer.getAdminPort(),
|
||||
adminConnector -> adminConnector.instanceLog(canalInstanceConfig.getName(), null, 100));
|
||||
|
||||
result.put("instance", canalInstanceConfig.getName());
|
||||
@@ -124,11 +134,11 @@ public class CanalInstanceServiceImpl implements CanalInstanceService {
|
||||
Boolean resutl = null;
|
||||
if ("start".equals(option)) {
|
||||
resutl = SimpleAdminConnectors.execute(nodeServer.getIp(),
|
||||
nodeServer.getPort(),
|
||||
nodeServer.getAdminPort(),
|
||||
adminConnector -> adminConnector.startInstance(canalInstanceConfig.getName()));
|
||||
} else if ("stop".equals(option)) {
|
||||
resutl = SimpleAdminConnectors.execute(nodeServer.getIp(),
|
||||
nodeServer.getPort(),
|
||||
nodeServer.getAdminPort(),
|
||||
adminConnector -> adminConnector.stopInstance(canalInstanceConfig.getName()));
|
||||
} else {
|
||||
return false;
|
||||
@@ -139,4 +149,5 @@ public class CanalInstanceServiceImpl implements CanalInstanceService {
|
||||
}
|
||||
return resutl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class NodeServerServiceImpl implements NodeServerService {
|
||||
int cnt = NodeServer.find.query()
|
||||
.where()
|
||||
.eq("ip", nodeServer.getIp())
|
||||
.eq("port", nodeServer.getPort())
|
||||
.eq("admin_port", nodeServer.getAdminPort())
|
||||
.findCount();
|
||||
if (cnt > 0) {
|
||||
throw new ServiceException("节点信息已存在");
|
||||
@@ -48,14 +48,14 @@ public class NodeServerServiceImpl implements NodeServerService {
|
||||
int cnt = NodeServer.find.query()
|
||||
.where()
|
||||
.eq("ip", nodeServer.getIp())
|
||||
.eq("port", nodeServer.getPort())
|
||||
.eq("admin_port", nodeServer.getAdminPort())
|
||||
.ne("id", nodeServer.getId())
|
||||
.findCount();
|
||||
if (cnt > 0) {
|
||||
throw new ServiceException("节点信息已存在");
|
||||
}
|
||||
|
||||
nodeServer.update("name", "ip", "port", "port2");
|
||||
nodeServer.update("name", "ip", "admin_port", "tcp_port", "metric_port");
|
||||
}
|
||||
|
||||
public void delete(Long id) {
|
||||
@@ -86,8 +86,8 @@ public class NodeServerServiceImpl implements NodeServerService {
|
||||
// get all nodes status
|
||||
for (NodeServer ns : nodeServers) {
|
||||
futures.add(executorService.submit(() -> {
|
||||
boolean status = SimpleAdminConnectors.execute(ns.getIp(), ns.getPort(), AdminConnector::check);
|
||||
ns.setStatus(status ? 1 : 0);
|
||||
boolean status = SimpleAdminConnectors.execute(ns.getIp(), ns.getAdminPort(), AdminConnector::check);
|
||||
ns.setStatus(status ? "1" : "0");
|
||||
return !status;
|
||||
}));
|
||||
}
|
||||
@@ -115,7 +115,7 @@ public class NodeServerServiceImpl implements NodeServerService {
|
||||
return "";
|
||||
}
|
||||
return SimpleAdminConnectors.execute(nodeServer.getIp(),
|
||||
nodeServer.getPort(),
|
||||
nodeServer.getAdminPort(),
|
||||
adminConnector -> adminConnector.canalLog(100));
|
||||
}
|
||||
|
||||
@@ -126,9 +126,9 @@ public class NodeServerServiceImpl implements NodeServerService {
|
||||
}
|
||||
Boolean result = null;
|
||||
if ("start".equals(option)) {
|
||||
result = SimpleAdminConnectors.execute(nodeServer.getIp(), nodeServer.getPort(), AdminConnector::start);
|
||||
result = SimpleAdminConnectors.execute(nodeServer.getIp(), nodeServer.getAdminPort(), AdminConnector::start);
|
||||
} else if ("stop".equals(option)) {
|
||||
result = SimpleAdminConnectors.execute(nodeServer.getIp(), nodeServer.getPort(), AdminConnector::stop);
|
||||
result = SimpleAdminConnectors.execute(nodeServer.getIp(), nodeServer.getAdminPort(), AdminConnector::stop);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -13,3 +13,7 @@ spring.datasource:
|
||||
hikari:
|
||||
maximum-pool-size: 10
|
||||
minimum-idle: 1
|
||||
|
||||
canal:
|
||||
adminUser: admin
|
||||
adminPasswd: admin
|
||||
|
||||
@@ -13,10 +13,11 @@ CREATE TABLE `canal_adapter_config` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`category` varchar(45) NOT NULL,
|
||||
`name` varchar(45) NOT NULL,
|
||||
`status` varchar(45) DEFAULT NULL,
|
||||
`content` text NOT NULL,
|
||||
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for canal_config
|
||||
@@ -25,11 +26,12 @@ DROP TABLE IF EXISTS `canal_config`;
|
||||
CREATE TABLE `canal_config` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(45) NOT NULL,
|
||||
`status` varchar(45) DEFAULT NULL,
|
||||
`content` text NOT NULL,
|
||||
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name_UNIQUE` (`name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for canal_instance_config
|
||||
@@ -38,11 +40,12 @@ DROP TABLE IF EXISTS `canal_instance_config`;
|
||||
CREATE TABLE `canal_instance_config` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(45) NOT NULL,
|
||||
`status` varchar(45) DEFAULT NULL,
|
||||
`content` text NOT NULL,
|
||||
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name_UNIQUE` (`name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for canal_node_server
|
||||
@@ -52,9 +55,10 @@ CREATE TABLE `canal_node_server` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(63) NOT NULL,
|
||||
`ip` varchar(63) NOT NULL,
|
||||
`port` int(11) DEFAULT NULL,
|
||||
`port2` int(11) DEFAULT NULL,
|
||||
`status` int(11) NOT NULL,
|
||||
`admin_port` int(11) DEFAULT NULL,
|
||||
`tcp_port` int(11) DEFAULT NULL,
|
||||
`metric_port` int(11) DEFAULT NULL,
|
||||
`status` varchar(45) DEFAULT NULL,
|
||||
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
@@ -73,7 +77,7 @@ CREATE TABLE `canal_user` (
|
||||
`avatar` varchar(255) DEFAULT NULL,
|
||||
`creation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of canal_user
|
||||
|
||||
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><title>Canal Admin</title><link href=/static/css/chunk-elementUI.18b11d0e.css rel=stylesheet><link href=/static/css/chunk-libs.5cf311f0.css rel=stylesheet><link href=/static/css/app.bb951cb3.css rel=stylesheet></head><body><noscript><strong>We're sorry but Canal Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/static/js/chunk-elementUI.667f4c87.js></script><script src=/static/js/chunk-libs.c04beefc.js></script><script>(function(e){function n(n){for(var r,c,f=n[0],a=n[1],i=n[2],h=0,d=[];h<f.length;h++)c=f[h],u[c]&&d.push(u[c][0]),u[c]=0;for(r in a)Object.prototype.hasOwnProperty.call(a,r)&&(e[r]=a[r]);l&&l(n);while(d.length)d.shift()();return o.push.apply(o,i||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var f=t[c];0!==u[f]&&(r=!1)}r&&(o.splice(n--,1),e=a(a.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function f(e){return a.p+"static/js/"+({}[e]||e)+"."+{"chunk-101fc062":"372a5ca5","chunk-137eaf06":"539d27c7","chunk-238a81e9":"da844a27","chunk-37c49cbf":"92ebe0ae","chunk-3fcdf643":"4b7133b8","chunk-1ef583f0":"c799c803","chunk-5560c396":"5eb91155","chunk-6f6d6145":"385d3c06","chunk-4f09fed2":"d107437b","chunk-69386cf0":"bdbe3f0c","chunk-7ec889b7":"192dc04c","chunk-e1a839e4":"7ee86dd8"}[e]+".js"}function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=[],t={"chunk-101fc062":1,"chunk-238a81e9":1,"chunk-37c49cbf":1,"chunk-1ef583f0":1,"chunk-5560c396":1,"chunk-6f6d6145":1,"chunk-4f09fed2":1,"chunk-69386cf0":1,"chunk-7ec889b7":1};c[e]?n.push(c[e]):0!==c[e]&&t[e]&&n.push(c[e]=new Promise(function(n,t){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-101fc062":"fad9926f","chunk-137eaf06":"31d6cfe0","chunk-238a81e9":"e8e2beee","chunk-37c49cbf":"efc21a9c","chunk-3fcdf643":"31d6cfe0","chunk-1ef583f0":"ec3a43f5","chunk-5560c396":"b660603c","chunk-6f6d6145":"bf63041a","chunk-4f09fed2":"70ec0b86","chunk-69386cf0":"741ff14e","chunk-7ec889b7":"c0585512","chunk-e1a839e4":"31d6cfe0"}[e]+".css",u=a.p+r,o=document.getElementsByTagName("link"),f=0;f<o.length;f++){var i=o[f],h=i.getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(h===r||h===u))return n()}var d=document.getElementsByTagName("style");for(f=0;f<d.length;f++){i=d[f],h=i.getAttribute("data-href");if(h===r||h===u)return n()}var l=document.createElement("link");l.rel="stylesheet",l.type="text/css",l.onload=n,l.onerror=function(n){var r=n&&n.target&&n.target.src||u,o=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");o.code="CSS_CHUNK_LOAD_FAILED",o.request=r,delete c[e],l.parentNode.removeChild(l),t(o)},l.href=u;var s=document.getElementsByTagName("head")[0];s.appendChild(l)}).then(function(){c[e]=0}));var r=u[e];if(0!==r)if(r)n.push(r[2]);else{var o=new Promise(function(n,t){r=u[e]=[n,t]});n.push(r[2]=o);var i,h=document.createElement("script");h.charset="utf-8",h.timeout=120,a.nc&&h.setAttribute("nonce",a.nc),h.src=f(e),i=function(n){h.onerror=h.onload=null,clearTimeout(d);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,t[1](o)}u[e]=void 0}};var d=setTimeout(function(){i({type:"timeout",target:h})},12e4);h.onerror=h.onload=i,document.head.appendChild(h)}return Promise.all(n)},a.m=e,a.c=r,a.d=function(e,n,t){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},a.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)a.d(t,r,function(n){return e[n]}.bind(null,r));return t},a.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="/",a.oe=function(e){throw console.error(e),e};var i=window["webpackJsonp"]=window["webpackJsonp"]||[],h=i.push.bind(i);i.push=n,i=i.slice();for(var d=0;d<i.length;d++)n(i[d]);var l=h;t()})([]);</script><script src=/static/js/app.38307ef0.js></script></body></html>
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><title>Canal Admin</title><link href=/static/css/chunk-elementUI.18b11d0e.css rel=stylesheet><link href=/static/css/chunk-libs.5cf311f0.css rel=stylesheet><link href=/static/css/app.bb951cb3.css rel=stylesheet></head><body><noscript><strong>We're sorry but Canal Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/static/js/chunk-elementUI.667f4c87.js></script><script src=/static/js/chunk-libs.c04beefc.js></script><script>(function(e){function n(n){for(var r,c,f=n[0],a=n[1],i=n[2],h=0,l=[];h<f.length;h++)c=f[h],u[c]&&l.push(u[c][0]),u[c]=0;for(r in a)Object.prototype.hasOwnProperty.call(a,r)&&(e[r]=a[r]);d&&d(n);while(l.length)l.shift()();return o.push.apply(o,i||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var f=t[c];0!==u[f]&&(r=!1)}r&&(o.splice(n--,1),e=a(a.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function f(e){return a.p+"static/js/"+({}[e]||e)+"."+{"chunk-101fc062":"372a5ca5","chunk-137eaf06":"539d27c7","chunk-238a81e9":"da844a27","chunk-37c49cbf":"92ebe0ae","chunk-3fcdf643":"4b7133b8","chunk-1ef583f0":"c799c803","chunk-5560c396":"5eb91155","chunk-6f6d6145":"385d3c06","chunk-4f09fed2":"d107437b","chunk-69386cf0":"bdbe3f0c","chunk-7ec889b7":"192dc04c","chunk-e1a839e4":"e9eb1b06"}[e]+".js"}function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=[],t={"chunk-101fc062":1,"chunk-238a81e9":1,"chunk-37c49cbf":1,"chunk-1ef583f0":1,"chunk-5560c396":1,"chunk-6f6d6145":1,"chunk-4f09fed2":1,"chunk-69386cf0":1,"chunk-7ec889b7":1};c[e]?n.push(c[e]):0!==c[e]&&t[e]&&n.push(c[e]=new Promise(function(n,t){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-101fc062":"fad9926f","chunk-137eaf06":"31d6cfe0","chunk-238a81e9":"e8e2beee","chunk-37c49cbf":"efc21a9c","chunk-3fcdf643":"31d6cfe0","chunk-1ef583f0":"ec3a43f5","chunk-5560c396":"b660603c","chunk-6f6d6145":"bf63041a","chunk-4f09fed2":"70ec0b86","chunk-69386cf0":"741ff14e","chunk-7ec889b7":"c0585512","chunk-e1a839e4":"31d6cfe0"}[e]+".css",u=a.p+r,o=document.getElementsByTagName("link"),f=0;f<o.length;f++){var i=o[f],h=i.getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(h===r||h===u))return n()}var l=document.getElementsByTagName("style");for(f=0;f<l.length;f++){i=l[f],h=i.getAttribute("data-href");if(h===r||h===u)return n()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=n,d.onerror=function(n){var r=n&&n.target&&n.target.src||u,o=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");o.code="CSS_CHUNK_LOAD_FAILED",o.request=r,delete c[e],d.parentNode.removeChild(d),t(o)},d.href=u;var s=document.getElementsByTagName("head")[0];s.appendChild(d)}).then(function(){c[e]=0}));var r=u[e];if(0!==r)if(r)n.push(r[2]);else{var o=new Promise(function(n,t){r=u[e]=[n,t]});n.push(r[2]=o);var i,h=document.createElement("script");h.charset="utf-8",h.timeout=120,a.nc&&h.setAttribute("nonce",a.nc),h.src=f(e),i=function(n){h.onerror=h.onload=null,clearTimeout(l);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,t[1](o)}u[e]=void 0}};var l=setTimeout(function(){i({type:"timeout",target:h})},12e4);h.onerror=h.onload=i,document.head.appendChild(h)}return Promise.all(n)},a.m=e,a.c=r,a.d=function(e,n,t){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},a.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)a.d(t,r,function(n){return e[n]}.bind(null,r));return t},a.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="/",a.oe=function(e){throw console.error(e),e};var i=window["webpackJsonp"]=window["webpackJsonp"]||[],h=i.push.bind(i);i.push=n,i=i.slice();for(var l=0;l<i.length;l++)n(i[l]);var d=h;t()})([]);</script><script src=/static/js/app.38307ef0.js></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -25,14 +25,19 @@
|
||||
<span>{{ scope.row.ip }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Admin 端口" min-width="100" align="center">
|
||||
<el-table-column label="admin 端口" min-width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.port }}
|
||||
{{ scope.row.adminPort }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="监控端口" min-width="100" align="center">
|
||||
<el-table-column label="tcp 端口" min-width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.port2 }}
|
||||
{{ scope.row.tcpPort }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="metric 端口" min-width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.metricPort }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column class-name="status-col" label="状态" min-width="150" align="center">
|
||||
@@ -65,11 +70,14 @@
|
||||
<el-form-item label="Server IP" prop="ip">
|
||||
<el-input v-model="nodeModel.ip" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Admin 端口" prop="port">
|
||||
<el-input v-model="nodeModel.port" placeholder="11110" type="number" />
|
||||
<el-form-item label="admin 端口" prop="adminPort">
|
||||
<el-input v-model="nodeModel.adminPort" placeholder="11110" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="监控端口" prop="port2">
|
||||
<el-input v-model="nodeModel.port2" placeholder="11112" type="number" />
|
||||
<el-form-item label="tcp 端口" prop="tcpPort">
|
||||
<el-input v-model="nodeModel.tcpPort" placeholder="11111" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="metric 端口" prop="metricPort">
|
||||
<el-input v-model="nodeModel.metricPort" placeholder="11112" type="number" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@@ -119,13 +127,14 @@ export default {
|
||||
id: undefined,
|
||||
name: null,
|
||||
ip: null,
|
||||
port: 11110,
|
||||
port2: 11112
|
||||
adminPort: 11110,
|
||||
tcpPort: 11111,
|
||||
metricPort: 11112
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: 'Server 名称不能为空', trigger: 'change' }],
|
||||
ip: [{ required: true, message: 'Server IP不能为空', trigger: 'change' }],
|
||||
port: [{ required: true, message: 'Server Admin端口不能为空', trigger: 'change' }]
|
||||
port: [{ required: true, message: 'Server admin端口不能为空', trigger: 'change' }]
|
||||
},
|
||||
dialogStatus: 'create'
|
||||
}
|
||||
@@ -147,8 +156,9 @@ export default {
|
||||
id: undefined,
|
||||
name: null,
|
||||
ip: null,
|
||||
port: null,
|
||||
port2: null
|
||||
adminPort: null,
|
||||
tcpPort: null,
|
||||
metricPort: null
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
@@ -222,7 +232,7 @@ export default {
|
||||
})
|
||||
},
|
||||
handleStart(row) {
|
||||
if (row.status !== 0) {
|
||||
if (row.status !== '0') {
|
||||
this.$message({ message: '当前Server不是停止状态,无法启动', type: 'error' })
|
||||
return
|
||||
}
|
||||
@@ -248,7 +258,7 @@ export default {
|
||||
})
|
||||
},
|
||||
handleStop(row) {
|
||||
if (row.status !== 1) {
|
||||
if (row.status !== '1') {
|
||||
this.$message({ message: '当前Server不是启动状态,无法停止', type: 'error' })
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user