Skip to content

Commit

Permalink
Merge pull request #494 from xichen1/node-config-upload-btn
Browse files Browse the repository at this point in the history
Add node config upload btn and Node join channel btn
  • Loading branch information
yeasy authored Nov 5, 2022
2 parents c9781f1 + 6d9e39b commit 69f38d9
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/api-engine/api/routes/node/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import shutil
import os
import threading
import yaml

from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import Paginator
Expand Down Expand Up @@ -746,6 +747,10 @@ def node_config(self, request, pk=None):
# Update yaml, zip files, and the database field
try:
new_config_file = request.data['file']
try:
yaml.safe_load(new_config_file)
except yaml.YAMLError:
return Response(err("Unable to parse this YAML file."), status=status.HTTP_400_BAD_REQUEST)
if os.path.exists("{}{}".format(dir_node, name)):
os.remove("{}{}".format(dir_node, name))
with open("{}{}".format(dir_node, name), 'wb+') as f:
Expand Down
2 changes: 2 additions & 0 deletions src/dashboard/src/locales/en-US/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export default {
'form.button.new': 'New',
'form.table.header.operation': 'Operation',
'form.menu.item.download': 'Download',
'form.menu.item.upload': 'Upload',
'form.menu.item.joinChannel': 'Join Channel',
'form.menu.item.delete': 'Delete',
'form.input.placeholder': 'Please input',
'form.menu.item.update': 'Update',
Expand Down
2 changes: 2 additions & 0 deletions src/dashboard/src/locales/en-US/operatorNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export default {
'Deleting node {name} may cause abnormality in the blockchain network. Confirm delete?',
'app.operator.node.delete.success': 'Delete Node Successful.',
'app.operator.node.download.success': 'Download Node Config File Successful.',
'app.operator.node.upload.success': 'Upload Node Config File Successful.',
'app.operator.node.joinChannel.success': 'Join Channel Successful',
'app.operator.node.operation.start.success': 'Start Node Successful.',
'app.operator.node.operation.stop.success': 'Stop Node Successful.',
'app.operator.node.operation.restart.success': 'Restart Node Successful.',
Expand Down
2 changes: 2 additions & 0 deletions src/dashboard/src/locales/zh-CN/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export default {
'form.button.new': '新建',
'form.table.header.operation': '操作',
'form.menu.item.download': '下载',
'form.menu.item.upload': '上传',
'form.menu.item.joinChannel': '加入通道',
'form.menu.item.delete': '删除',
'form.input.placeholder': '请输入',
'form.menu.item.update': '更新',
Expand Down
2 changes: 2 additions & 0 deletions src/dashboard/src/locales/zh-CN/operatorNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default {
'app.operator.node.delete.confirm': '删除节点 {name} 可能导致区块链网络异常,是否确认删除?',
'app.operator.node.delete.success': '删除节点成功。',
'app.operator.node.download.success': '下载节点配置文件成功。',
'app.operator.node.upload.success': '上传节点配置文件成功。',
'app.operator.node.joinChannel.success': '加入通道成功。',
'app.operator.node.operation.start.success': '启动节点成功。',
'app.operator.node.operation.stop.success': '停止节点成功。',
'app.operator.node.operation.restart.success': '重启节点成功。',
Expand Down
20 changes: 20 additions & 0 deletions src/dashboard/src/models/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
operateNode,
createNode,
downloadNodeConfig,
uploadNodeConfig,
nodeJoinChannel,
} from '@/services/node';

export default {
Expand Down Expand Up @@ -97,6 +99,24 @@ export default {
callback(response);
}
},
*uploadNodeConfig({ payload, callback }, { call }) {
const response = yield call(uploadNodeConfig, payload);
if (callback) {
callback({
payload,
...response,
});
}
},
*nodeJoinChannel({ payload, callback }, { call }) {
const response = yield call(nodeJoinChannel, payload);
if (callback) {
callback({
payload,
...response,
});
}
},
},
reducers: {
save(state, { payload }) {
Expand Down
107 changes: 107 additions & 0 deletions src/dashboard/src/pages/Operator/Node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
Select,
InputNumber,
Badge,
Upload,
} from 'antd';
import { DownOutlined, PlusOutlined } from '@ant-design/icons';
import moment from 'moment';
Expand Down Expand Up @@ -540,6 +541,52 @@ class Index extends PureComponent {
URL.revokeObjectURL(link.href);
};

handleUploadConfig = (row, formData) => {
const { dispatch } = this.props;
const params = {
id: row.id,
form: formData,
};
dispatch({
type: 'node/uploadNodeConfig',
payload: params,
callback: this.uploadCallBack,
});
};

uploadCallBack = () => {
const { intl } = this.props;
message.success(
intl.formatMessage({
id: 'app.operator.node.upload.success',
defaultMessage: 'Upload config file succeed',
})
);
};

handleJoinChannel = (row, formData) => {
const { dispatch } = this.props;
const params = {
id: row.id,
form: formData,
};
dispatch({
type: 'node/nodeJoinChannel',
payload: params,
callback: this.joinCallBack,
});
};

joinCallBack = () => {
const { intl } = this.props;
message.success(
intl.formatMessage({
id: 'app.operator.node.joinChannel.success',
defaultMessage: 'Join Channel succeed',
})
);
};

render() {
const { selectedRows, registerUserFormVisible, targetNodeId, createModalVisible } = this.state;

Expand Down Expand Up @@ -593,6 +640,13 @@ class Index extends PureComponent {
return statusOfBadge;
}

// prevent the default http upload request in antd
const dummyRequest = ({ onSuccess }) => {
setTimeout(() => {
onSuccess('ok');
}, 0);
};

const menu = record => (
<Menu>
{record.type === 'ca' && (
Expand All @@ -612,6 +666,59 @@ class Index extends PureComponent {
</a>
</Menu.Item>
)}
{(record.type === 'peer' || record.type === 'orderer') && (
<Menu.Item>
<Upload
{...{
showUploadList: false,
customRequest: dummyRequest,
onChange: info => {
if (info.file.name.split('.').pop() !== 'yaml') {
message.error('Only accept yaml file.');
return;
}
if (info.file.status === 'done') {
const formData = new FormData();
formData.append('file', info.fileList[0].originFileObj);
this.handleUploadConfig(record, formData);
}
},
}}
>
<a style={{ color: 'inherit' }}>
{intl.formatMessage({ id: 'form.menu.item.upload', defaultMessage: 'Upload' })}
</a>
</Upload>
</Menu.Item>
)}
{record.type === 'peer' && (
<Menu.Item>
<Upload
{...{
showUploadList: false,
customRequest: dummyRequest,
onChange: info => {
if (info.file.name.split('.').pop() !== 'block') {
message.error('Only accept block file.');
return;
}
if (info.file.status === 'done') {
const formData = new FormData();
formData.append('file', info.fileList[0].originFileObj);
this.handleJoinChannel(record, formData);
}
},
}}
>
<a style={{ color: 'inherit' }}>
{intl.formatMessage({
id: 'form.menu.item.joinChannel',
defaultMessage: 'Join Channel',
})}
</a>
</Upload>
</Menu.Item>
)}
<Menu.Item>
<a onClick={() => this.handleDeleteNode(record)}>
{intl.formatMessage({ id: 'form.menu.item.delete', defaultMessage: 'Delete' })}
Expand Down
14 changes: 14 additions & 0 deletions src/dashboard/src/services/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,17 @@ export async function downloadNodeConfig(params) {
getResponse: true,
});
}

export async function uploadNodeConfig(params) {
return request(`/api/v1/nodes/${params.id}/config`, {
method: 'POST',
body: params.form,
});
}

export async function nodeJoinChannel(params) {
return request(`/api/v1/nodes/${params.id}/block`, {
method: 'POST',
body: params.form,
});
}

0 comments on commit 69f38d9

Please sign in to comment.