| <!-- |
| |
| Licensed 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. |
| |
| --> |
| <template> |
| <div class="app-container"> |
| <div class="createPost-container"> |
| <el-form :inline="true" :model="postForm" class="form-container"> |
| <el-form-item class="postInfo-container-item" label="Cluster"> |
| <el-select v-model="postForm.cluster" placeholder="select cluster" @change="getBrokersList()"> |
| <el-option v-for="(item,index) in clustersListOptions" :key="item+index" :label="item" :value="item"/> |
| </el-select> |
| </el-form-item> |
| <el-form-item class="postInfo-container-item" label="Broker"> |
| <el-select v-model="postForm.broker" placeholder="select broker" @change="changeBrokerInfo()"> |
| <el-option v-for="(item,index) in brokersListOptions" :key="item+index" :label="item" :value="item"/> |
| </el-select> |
| </el-form-item> |
| <el-button type="primary" @click="handleHeartBeat">Heartbeat</el-button> |
| <el-button type="primary" @click="handleRuntimeConfig">Runtime Config</el-button> |
| </el-form> |
| <el-table |
| :data="brokerStats" |
| border |
| style="width: 100%"> |
| <el-table-column :label="$t('common.inMsg')" prop="inMsg"/> |
| <el-table-column :label="$t('common.outMsg')" prop="outMsg"/> |
| <el-table-column :label="$t('common.inBytes')" prop="inBytes"/> |
| <el-table-column :label="$t('common.outBytes')" prop="outBytes"/> |
| </el-table> |
| <h4>Owned Namespaces</h4> |
| <el-table |
| :key="bundleTableKey" |
| :data="bundleList" |
| border |
| fit |
| highlight-current-row |
| style="width: 100%;"> |
| <el-table-column :label="$t('tenant.label')" align="center" min-width="100px"> |
| <template slot-scope="scope"> |
| <router-link :to="'/management/tenants/tenantInfo/' + scope.row.tenant + '?tab=namespaces'" class="link-type"> |
| <span>{{ scope.row.tenant }}</span> |
| </router-link> |
| </template> |
| </el-table-column> |
| <el-table-column :label="$t('namespace.label')" align="center" min-width="100px"> |
| <template slot-scope="scope"> |
| <router-link :to="'/management/namespaces/' + scope.row.tenant + '/' + scope.row.namespace + '/namespace?tab=overview'" class="link-type"> |
| <span>{{ scope.row.namespace }}</span> |
| </router-link> |
| </template> |
| </el-table-column> |
| <el-table-column :label="$t('namespace.bundle.label')" align="center" min-width="100px"> |
| <template slot-scope="scope"> |
| <span>{{ scope.row.bundle }}</span> |
| </template> |
| </el-table-column> |
| <el-table-column :label="$t('namespace.bundle.operation')" align="center" class-name="small-padding fixed-width"> |
| <template slot-scope="scope"> |
| <el-button size="medium" type="danger" icon="el-icon-download" @click="handleUnloadBundle(scope.row)">Unload</el-button> |
| </template> |
| </el-table-column> |
| </el-table> |
| <h4>Namespace Isolation Policies</h4> |
| <el-table |
| :data="isolationPolicyList" |
| border |
| fit |
| highlight-current-row |
| style="width: 100%;"> |
| <el-table-column :label="$t('ip.nameLabel')" align="center" min-width="100px"> |
| <template slot-scope="scope"> |
| <router-link :to="'/management/clusters/' + scope.row.cluster + '/' + scope.row.isolationPolicy + '/namespaceIsolationPolicy'" class="link-type"> |
| <span>{{ scope.row.isolationPolicy }}</span> |
| </router-link> |
| </template> |
| </el-table-column> |
| <el-table-column :label="$t('ip.numPBLabel')" align="center" min-width="100px"> |
| <template slot-scope="scope"> |
| <span>{{ scope.row.primaryBrokers }}</span> |
| </template> |
| </el-table-column> |
| <el-table-column :label="$t('ip.numSBLabel')" align="center" min-width="100px"> |
| <template slot-scope="scope"> |
| <span>{{ scope.row.secondaryBrokers }}</span> |
| </template> |
| </el-table-column> |
| </el-table> |
| <el-dialog :visible.sync="dialogFormVisible"> |
| <jsonEditor :value="jsonValue"/> |
| </el-dialog> |
| </div> |
| </div> |
| </template> |
| |
| <script> |
| import { fetchClusters } from '@/api/clusters' |
| import { fetchBrokerStatsMetrics, fetchBrokerStatsTopics } from '@/api/brokerStats' |
| import { fetchBrokersHealth, fetchBrokers } from '@/api/brokers' |
| import { fetchIsolationPolicies } from '@/api/isolationPolicies' |
| import { unloadBundleOnBroker } from '@/api/namespaces' |
| import { fetchBrokersRuntimeConfiguration } from '@/api/brokers' |
| import jsonEditor from '@/components/JsonEditor' |
| import Pagination from '@/components/Pagination' // Secondary package based on el-pagination |
| import MdInput from '@/components/MDinput' |
| import { isValidResponse } from '@/utils/http' |
| import { formatBytes } from '@/utils/index' |
| import { numberFormatter } from '@/filters/index' |
| |
| const defaultForm = { |
| cluster: '', |
| broker: '' |
| } |
| export default { |
| name: 'BrokerInfo', |
| components: { |
| Pagination, |
| MdInput, |
| jsonEditor |
| }, |
| data() { |
| return { |
| postForm: Object.assign({}, defaultForm), |
| clustersListOptions: [], |
| brokersListOptions: [], |
| brokerStats: [], |
| bundleTableKey: 0, |
| bundleList: [], |
| isolationPolicyList: [], |
| isolationPolicyTableKey: 0, |
| dialogFormVisible: false, |
| jsonValue: {}, |
| firstInit: false |
| } |
| }, |
| created() { |
| this.postForm.cluster = this.$route.params && this.$route.params.cluster |
| this.postForm.broker = this.$route.params && this.$route.params.broker |
| this.firstInit = true |
| this.getBrokerInfo() |
| this.getBrokerStats() |
| this.getIsolationPolicy() |
| this.getClusterList() |
| this.getBrokersList() |
| }, |
| methods: { |
| getBrokerInfo() { |
| fetchBrokerStatsTopics(this.postForm.broker).then(response => { |
| if (!response.data) return |
| this.brokerStatsTopic = response.data |
| if ((typeof this.brokerStatsTopic) === 'string') { |
| // failed to fetch broker stats |
| this.brokerStatsTopic = {} |
| this.$notify({ |
| title: 'error', |
| message: 'Failed to fetch broker stats from broker ' + this.postForm.broker, |
| type: 'error', |
| duration: 3000 |
| }) |
| } |
| for (var tenantNamespace in this.brokerStatsTopic) { |
| var tn = tenantNamespace.split('/') |
| for (var bundle in this.brokerStatsTopic[tenantNamespace]) { |
| var ownedNamespace = {} |
| ownedNamespace['tenant'] = tn[0] |
| ownedNamespace['namespace'] = tn[1] |
| ownedNamespace['bundle'] = bundle |
| this.bundleList.push(ownedNamespace) |
| } |
| } |
| }) |
| }, |
| changeBrokerInfo() { |
| this.$router.push({ path: '/management/brokers/' + this.postForm.cluster + '/' + this.postForm.broker + '/broker' }) |
| }, |
| getBrokerStats() { |
| var throughputIn = 0 |
| var throughputOut = 0 |
| var bandwidthIn = 0 |
| var bandwidthOut = 0 |
| fetchBrokerStatsMetrics(this.postForm.broker).then(response => { |
| for (var m = 0; m < response.data.length; m++) { |
| if (response.data[m].dimensions.hasOwnProperty('namespace')) { |
| if (response.data[m].dimensions.namespace.split('/').length === 2) { |
| throughputIn += response.data[m].metrics.brk_in_tp_rate |
| throughputOut += response.data[m].metrics.brk_out_tp_rate |
| bandwidthIn += response.data[m].metrics.brk_in_rate |
| bandwidthOut += response.data[m].metrics.brk_out_rate |
| } |
| } |
| } |
| this.brokerStats.push({ |
| 'inBytes': formatBytes(throughputIn), |
| 'outBytes': formatBytes(throughputOut), |
| 'inMsg': numberFormatter(bandwidthIn, 2), |
| 'outMsg': numberFormatter(bandwidthOut, 2) |
| }) |
| }) |
| }, |
| getClusterList() { |
| fetchClusters(this.listQuery).then(response => { |
| if (!response.data) return |
| for (var i = 0; i < response.data.data.length; i++) { |
| this.clustersListOptions.push(response.data.data[i].cluster) |
| } |
| }) |
| }, |
| getIsolationPolicy() { |
| fetchIsolationPolicies(this.postForm.cluster).then(res => { |
| var tempIsolationPolicy = [] |
| for (var policy in res.data) { |
| for (var i in res.data[policy].primary) { |
| var regexPrimary = new RegExp(res.data[policy].primary[i]) |
| if (regexPrimary.test(this.postFormbroker)) { |
| if (tempIsolationPolicy.indexOf(policy) < 0) { |
| tempIsolationPolicy.push(policy) |
| } |
| } |
| } |
| for (var j in res.data[policy].secondary) { |
| var regexSecondary = new RegExp(res.data[policy].secondary[j]) |
| if (regexSecondary.test(this.postFormbroker)) { |
| if (tempIsolationPolicy.indexOf(policy) < 0) { |
| tempIsolationPolicy.push(policy) |
| } |
| } |
| } |
| if (tempIsolationPolicy.indexOf(policy) >= 0) { |
| this.isolationPolicyList.push({ |
| 'cluster': this.postForm.cluster, |
| 'isolationPolicy': policy, |
| 'primaryBrokers': res.data[policy].primary.length, |
| 'secondaryBrokers': res.data[policy].secondary.length |
| }) |
| } |
| } |
| }) |
| }, |
| getBrokersList() { |
| fetchBrokers(this.postForm.cluster).then(response => { |
| if (!response.data) return |
| if (this.firstInit) { |
| this.firstInit = false |
| } else { |
| this.postForm.broker = '' |
| } |
| this.brokersListOptions = [] |
| for (var i = 0; i < response.data.data.length; i++) { |
| this.brokersListOptions.push(response.data.data[i].broker) |
| } |
| }) |
| }, |
| handleUnloadBundle(row) { |
| unloadBundleOnBroker(this.postForm.broker, row.tenant + '/' + row.namespace, row.bundle).then(response => { |
| if (isValidResponse(response)) { |
| this.$notify({ |
| title: 'success', |
| message: 'Successfully unload namespace bundle from the broker', |
| type: 'success', |
| duration: 3000 |
| }) |
| } else { |
| this.$notify({ |
| title: 'error', |
| message: 'Failed to unload namespace bundle from the broker : ' + response.data, |
| type: 'error', |
| duration: 3000 |
| }) |
| } |
| }) |
| }, |
| handleHeartBeat() { |
| fetchBrokersHealth(this.postForm.broker).then(response => { |
| if (isValidResponse(response)) { |
| this.$notify({ |
| title: 'success', |
| message: 'Health Check success', |
| type: 'success', |
| duration: 3000 |
| }) |
| } else { |
| this.$notify({ |
| title: 'error', |
| message: 'Health Check failed: \n' + response.data, |
| type: 'error', |
| duration: 3000 |
| }) |
| } |
| }) |
| }, |
| handleRuntimeConfig() { |
| fetchBrokersRuntimeConfiguration(this.postForm.broker).then(response => { |
| this.dialogFormVisible = true |
| this.jsonValue = response.data |
| }) |
| } |
| } |
| } |
| </script> |