init data management module

This commit is contained in:
silenceqi 2020-11-10 22:01:48 +08:00
parent bb1baa2f20
commit f95e276e19
10 changed files with 335 additions and 65 deletions

View File

@ -50,13 +50,26 @@ export default [
path: '/data',
name: 'data',
icon: 'database',
component: './List/TableList',
routes: [
{
path: '/list/table-list',
path: '/data/pipes',
name: 'pipes',
component: './List/TableList',
}, {
component: './DataManagement/Pipes',
routes: [
{
path: '/data/pipes',
redirect: '/data/pipes/logstash',
},
{
path: '/data/pipes/logstash',
component: './DataManagement/LogstashConfig',
},
{
path: '/data/pipes/ingestpipeline',
component: './DataManagement/IngestPipeline',
},
]
},{
path: '/list/table-list',
name: 'index',
component: './List/TableList',
@ -138,18 +151,6 @@ export default [
},
]
},
{
path: '/data',
icon: 'form',
name: 'data',
routes: [
{
path: '/data/logstash',
name: 'logstash',
component: './DataManagement/LogstashConfig',
}
],
},
// // forms
// {

View File

@ -0,0 +1,56 @@
var logstashConf = {
jdbc: {
type: 'oracle',
config: ` jdbc_driver_library => "/etc/logstash/drivers/ojdbc8.jar"
jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
jdbc_connection_string => "jdbc:oracle:test:@192.168.1.68:1521/testdb"
jdbc_user => "testuser"
jdbc_password => "testpwd"
jdbc_paging_enabled => "true"
jdbc_page_size => "1000"
schedule => "*/1 * * * *"
statement => "SELECT a.SID, a.SERIAL#, c.spid, a.USERNAME, a.SQL_ID, a.PROGRAM, a.TERMINAL, a.MACHINE, a.MODULE, a.LOGON_TIME, a.EVENT, a.seconds_in_wait, a.status, b.sql_text FROM v$session a, v$sqlarea b, v$process c WHERE a.sql_id = b.sql_id AND c.addr = a.paddr AND a.status = 'ACTIVE' AND a.USERNAME NOT IN ('SYS', 'SYSMAN', 'DBSNMP')"
last_run_metadata_path =>"/tmp/logstash_jdbc_last_run_oracle-xxfnd-log-messages.txt"
id => "oracle-jdbc-input"
add_field => { "[labels][application]" => "oracle12.1" }
add_field => { "[labels][environment]" => "uat" }
add_field => { "[labels][location]" => "beijing" }
add_field => { "[labels][business]" => "jxoic" }
add_field => { "[labels][pdb]" => "testdb" }
add_field => { "[cloud][provider]" => "aws" }
add_field => { "[cloud][region]" => "cn-north-1" }
add_field => { "[host][ip]" => "192.168.1.68" }`
},
kafka: {
config: ` codec => json
bootstrap_servers => "192.168.1.68:9092,192.168.1.60:9092,192.168.1.61:9092"
client_id=> "logstash_pipeline_syslog_input"
security_protocol=> "PLAINTEXT"
topics=> "syslog"
consumer_threads => "1"
group_id=> "logstash-1"
decorate_events=> true`
},
};
export default {
'get /data/logstash/config': function (req, res) {
setTimeout(() => {
res.json(logstashConf);
}, 1500);
},
'POST /data/logstash/config': (req, res) => {
Object.assign(logstashConf, req.body);
console.log(logstashConf,1);
setTimeout(() => {
res.send({ message: 'Ok' });
},2000);
},
};

View File

@ -135,10 +135,6 @@ export default {
'menu.account.trigger': 'Trigger Error',
'menu.account.logout': 'Logout',
'menu.data':'Data Management',
'menu.data.logstash': 'Logstash Configuration',
'menu.data.ingestpipline': 'Elasticsearch Ingest Pipline Management',
'app.login.message-invalid-credentials': 'Invalid username or passwordadmin/888888',
'app.login.message-invalid-verification-code': 'Invalid verification code',
'app.login.tab-login-credentials': 'Credentials',

View File

@ -24,6 +24,9 @@ export default {
'validation.date.required': '请选择起止日期',
'validation.goal.required': '请输入目标描述',
'validation.standard.required': '请输入衡量标准',
'validation.dbtype.required':"请选择数据库类型",
'validation.logstashconf.required':"请输入Logstash jdbc配置",
'validation.kafkaconf.required':"请输入Logstash Kafka配置",
'form.optional': '(选填)',
'form.submit': '提交',
'form.save': '保存',
@ -57,6 +60,11 @@ export default {
'form.publicUsers.option.A': '同事甲',
'form.publicUsers.option.B': '同事乙',
'form.publicUsers.option.C': '同事丙',
'form.dbtype.label':'数据库类型',
'form.logstash.jdbcconf.label':"Logstash JDBC 配置",
'form.logstash.jdbcconf.placeholder':"请输入JDBC配置",
'form.logstash.kafkaconf.label':"Logstash Kafka 配置",
'form.logstash.kafkaconf.placeholder':"请输入Kafka配置",
'component.globalHeader.search': '站内搜索',
'component.globalHeader.search.example1': '搜索提示一',
'component.globalHeader.search.example2': '搜索提示二',
@ -135,10 +143,6 @@ export default {
'menu.account.trigger': '触发报错',
'menu.account.logout': '退出登录',
'menu.data':'数据管理',
'menu.data.logstash': 'Logstash配置管理',
'menu.data.ingestpipline': 'Elasticsearch Ingest Pipline 管理',
'app.login.message-invalid-credentials': '账户或密码错误admin/888888',
'app.login.message-invalid-verification-code': '验证码错误',
'app.login.tab-login-credentials': '账户密码登录',

View File

@ -0,0 +1,82 @@
import React, { Component,Fragment } from 'react';
import { connect } from 'dva';
import { Card,Form,Input, Select,Button } from 'antd';
const { Option } = Select;
import { formatMessage, FormattedMessage } from 'umi/locale';
import DescriptionList from '@/components/DescriptionList';
import styles from '../profile/AdvancedProfile.less';
const { Description } = DescriptionList;
const FormItem = Form.Item;
const { TextArea } = Input;
@connect(({ profile, loading }) => ({
profile,
loading: loading.effects['profile/fetchBasic'],
}))
@Form.create()
class IngestPipeline extends Component {
state = {
operationkey: 'tab1'
};
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'profile/fetchBasic',
});
}
onOperationTabChange = key => {
this.setState({ operationkey: key });
};
handleSubmit = e => {
const { dispatch, form } = this.props;
e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
dispatch({
type: 'form/submitRegularForm',
payload: values,
});
}
});
};
render() {
const { operationkey } = this.state;
const { submitting } = this.props;
const {
form: { getFieldDecorator, getFieldValue },
} = this.props;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 7 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
md: { span: 10 },
},
};
const submitFormLayout = {
wrapperCol: {
xs: { span: 24, offset: 0 },
sm: { span: 10, offset: 7 },
},
};
return (
<Fragment>
<Card
className={styles.tabsCard}
bordered={false}
onTabChange={this.onOperationTabChange}
>
<div>unimplement, waiting to do</div>
</Card>
</Fragment>
);
}
}
export default IngestPipeline;

View File

@ -1,10 +1,9 @@
import React, { Component } from 'react';
import React, { Component,Fragment } from 'react';
import { connect } from 'dva';
import { Card,Form,Input, Select,Button } from 'antd';
import { Card,Form,Input, Select,Button,message } from 'antd';
const { Option } = Select;
import { formatMessage, FormattedMessage } from 'umi/locale';
import DescriptionList from '@/components/DescriptionList';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import styles from '../profile/AdvancedProfile.less';
const { Description } = DescriptionList;
const FormItem = Form.Item;
@ -20,20 +19,22 @@ const operationTabList = [
}
];
@connect(({ profile, loading }) => ({
profile,
loading: loading.effects['profile/fetchBasic'],
@connect(({logstash,loading }) => ({
data: logstash.logstash,
loading: loading.models.logstash,
submitting: loading.effects['logstash/submitLogstashConfig'],
}))
@Form.create()
class LogstashConfig extends Component {
state = {
operationkey: 'tab1'
operationkey: 'tab1',
};
componentDidMount() {
message.loading('数据加载中..', 'initdata');
const { dispatch } = this.props;
dispatch({
type: 'profile/fetchBasic',
type: 'logstash/queryInitialLogstashConfig',
});
}
onOperationTabChange = key => {
@ -44,9 +45,22 @@ class LogstashConfig extends Component {
e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
let pdata = {
jdbc:{
type: values.dbtype,
config: values.logstash.jdbcconf,
},
};
if(e.target.name="kafka"){
pdata={
kafka:{
config: values.logstash.kafkaconf,
},
}
}
dispatch({
type: 'form/submitRegularForm',
payload: values,
type: 'logstash/submitLogstashConfig',
payload: pdata,
});
}
});
@ -54,7 +68,7 @@ class LogstashConfig extends Component {
render() {
const { operationkey } = this.state;
const { submitting } = this.props;
const { submitting, data, loading } = this.props;
const {
form: { getFieldDecorator, getFieldValue },
} = this.props;
@ -62,11 +76,12 @@ class LogstashConfig extends Component {
labelCol: {
xs: { span: 24 },
sm: { span: 7 },
md:{span:5},
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
md: { span: 10 },
md: { span: 15 },
},
};
const submitFormLayout = {
@ -78,17 +93,18 @@ class LogstashConfig extends Component {
const contentList = {
tab1: (
<div>
<Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>
<FormItem {...formItemLayout} label={<FormattedMessage id="form.goal.label" />}>
{getFieldDecorator('goal', {
<Form onSubmit={this.handleSubmit} name="jdbc" hideRequiredMark style={{ marginTop: 8 }}>
<FormItem {...formItemLayout} label={<FormattedMessage id="form.dbtype.label" />}>
{getFieldDecorator('dbtype', {
initialValue: data.jdbc.type,
rules: [
{
required: true,
message: formatMessage({ id: 'validation.goal.required' }),
message: formatMessage({ id: 'validation.dbtype.required' }),
},
],
})(
<Select defaultValue="mysql" style={{ width: 150 }}>
<Select placeholder="Please select" style={{ width: 150 }}>
<Option value="mysql">mysql</Option>
<Option value="postgresql">postgresql</Option>
<Option value="oracle">oracle</Option>
@ -96,19 +112,20 @@ class LogstashConfig extends Component {
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} label={<FormattedMessage id="form.goal.label" />}>
{getFieldDecorator('goal', {
<FormItem {...formItemLayout} label={<FormattedMessage id="form.logstash.jdbcconf.label" />}>
{getFieldDecorator('logstash.jdbcconf', {
initialValue: data.jdbc.config,
rules: [
{
required: true,
message: formatMessage({ id: 'validation.goal.required' }),
message: formatMessage({ id: 'validation.logstashconf.required' }),
},
],
})(
<TextArea
style={{ minHeight: 32 }}
placeholder={formatMessage({ id: 'form.goal.placeholder' })}
rows={4}
style={{ minHeight: 32, width: '100%' }}
placeholder={formatMessage({ id: 'form.logstash.jdbcconf.placeholder' })}
rows={12}
/>
)}
</FormItem>
@ -121,37 +138,43 @@ class LogstashConfig extends Component {
</div>
),
tab2: (
<Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>
<FormItem {...formItemLayout} label={<FormattedMessage id="form.goal.label" />}>
{getFieldDecorator('goal', {
<Form onSubmit={this.handleSubmit} name="kafka" hideRequiredMark style={{ marginTop: 8 }}>
<FormItem {...formItemLayout} label={<FormattedMessage id="form.logstash.kafkaconf.label" />}>
{getFieldDecorator('logstash.kafkaconf', {
initialValue: data.kafka.config,
rules: [
{
required: true,
message: formatMessage({ id: 'validation.goal.required' }),
message: formatMessage({ id: 'validation.kafkaconf.required' }),
},
],
})(
<TextArea
style={{ minHeight: 32 }}
placeholder={formatMessage({ id: 'form.goal.placeholder' })}
rows={4}
placeholder={formatMessage({ id: 'form.logstash.kafkaconf.placeholder' })}
rows={12}
/>
)}
</FormItem>
</Form>
<FormItem {...submitFormLayout} style={{ marginTop: 32 }}>
<Button type="primary" htmlType="submit" loading={submitting}>
<FormattedMessage id="form.submit" />
</Button>
</FormItem>
</Form>
)
};
return (
<PageHeaderWrapper >
<Card
className={styles.tabsCard}
bordered={false}
tabList={operationTabList}
onTabChange={this.onOperationTabChange}
>
{contentList[operationkey]}
</Card>
</PageHeaderWrapper>
<Fragment>
<Card
className={styles.tabsCard}
bordered={false}
tabList={operationTabList}
onTabChange={this.onOperationTabChange}
>
{contentList[operationkey]}
</Card>
</Fragment>
);
}
}

View File

@ -0,0 +1,47 @@
import React, { Component } from 'react';
import router from 'umi/router';
import { connect } from 'dva';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
@connect()
class Pipes extends Component {
handleTabChange = key => {
const { match } = this.props;
switch (key) {
case 'logstash':
router.push(`${match.url}/logstash`);
break;
case 'ingestpipeline':
router.push(`${match.url}/ingestpipeline`);
break;
default:
break;
}
}
render() {
const tabList = [
{
key: 'logstash',
tab: 'Logstash 配置管理',
},
{
key: 'ingestpipeline',
tab: 'Elasticsearch Ingest Pipeline 管理',
}
];
const { match, children, location } = this.props;
return (
<PageHeaderWrapper
tabList={tabList}
tabActiveKey={location.pathname.replace(`${match.path}/`, '')}
onTabChange={this.handleTabChange}
>
{children}
</PageHeaderWrapper>
);
}
}
export default Pipes;

View File

@ -0,0 +1,49 @@
import { routerRedux } from 'dva/router';
import { message } from 'antd';
import { getLogstashConfig, saveLogstashConfig } from '@/services/datamanagement';
export default {
namespace: 'logstash',
state: {
logstash: {
jdbc:{},
kafka:{},
}
},
effects: {
*queryInitialLogstashConfig(_, {call, put}){
const istate = yield call(getLogstashConfig);
yield put({
type: 'initLogstashState',
payload: istate,
});
message.loading('数据加载完成', 'initdata');
},
*submitLogstashConfig({payload}, {call, put}){
console.log(payload);
const rel = yield call(saveLogstashConfig, payload);
if(rel.message == "Ok") {
message.success('提交成功');
yield put({
type: 'updateState',
payload: payload,
});
}
}
},
reducers: {
initLogstashState(state, { payload: istate }) {
return {
logstash: istate
}
},
updateState(state, {payload: newState}){
var obj = {
...state,
logstash: Object.assign(state.logstash, newState),
};
return obj;
},
},
};

View File

@ -123,4 +123,4 @@ export async function queryNotices() {
export async function getFakeCaptcha(mobile) {
return request(`/api/captcha?mobile=${mobile}`);
}
}

View File

@ -0,0 +1,12 @@
import request from '@/utils/request';
export async function getLogstashConfig(){
return request('/data/logstash/config');
}
export async function saveLogstashConfig(config){
return request('/data/logstash/config', {
method: 'POST',
body: config,
});
}