add config management #242
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
index 86d9d2b..44febab 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
@@ -29,6 +29,7 @@
public static final String PATH_SEPARATOR = "/";
public static final String GROUP_KEY = "group";
public static final String CONFIG_KEY = "config";
+ public static final String DUBBO_PROPERTY = "dubbo.properties";
public static final String PROVIDER_SIDE = "provider";
public static final String CONSUMER_SIDE = "consumer";
public static final String CATEGORY_KEY = "category";
@@ -52,6 +53,7 @@
public static final String PROVIDERS_CATEGORY = "providers";
public static final String CONSUMERS_CATEGORY = "consumers";
public static final String SPECIFICATION_VERSION_KEY = "specVersion";
+ public static final String GLOBAL_CONFIG = "global";
public static final Set<String> CONFIGS = new HashSet<>();
static {
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
index a9c088d..1c6b4bd 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/config/ConfigCenter.java
@@ -23,12 +23,14 @@
import org.apache.dubbo.admin.registry.config.GovernanceConfiguration;
import org.apache.dubbo.admin.registry.metadata.MetaDataCollector;
import org.apache.dubbo.admin.registry.metadata.impl.NoOpMetadataCollector;
+import org.apache.dubbo.admin.service.ManagementService;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -62,6 +64,7 @@
private URL metadataUrl;
+
/*
* generate dynamic configuration client
*/
@@ -79,8 +82,10 @@
if (StringUtils.isNotEmpty(config)) {
Arrays.stream(config.split("\n")).forEach( s -> {
if(s.startsWith(Constants.REGISTRY_ADDRESS)) {
- registryUrl = formUrl(s.split("=")[1].trim(), group, username, password);
+ String registryAddress = s.split("=")[1].trim();
+ registryUrl = formUrl(registryAddress, group, username, password);
} else if (s.startsWith(Constants.METADATA_ADDRESS)) {
+ String metadataAddress = s.split("=")[1].trim();
metadataUrl = formUrl(s.split("=")[1].trim(), group, username, password);
}
});
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ManagementController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ManagementController.java
new file mode 100644
index 0000000..412a797
--- /dev/null
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/ManagementController.java
@@ -0,0 +1,90 @@
+/*
+ * 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.dubbo.admin.controller;
+
+import org.apache.dubbo.admin.common.exception.ParamValidationException;
+import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
+import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.model.dto.ConfigDTO;
+import org.apache.dubbo.admin.service.ManagementService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@RestController
+@RequestMapping("/api/{env}/manage")
+public class ManagementController {
+
+ private final ManagementService managementService;
+ private static Pattern CLASS_NAME_PATTERN = Pattern.compile("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)*[a-zA-Z_$][a-zA-Z\\d_$]*");
+
+
+ @Autowired
+ public ManagementController(ManagementService managementService) {
+ this.managementService = managementService;
+ }
+
+ @RequestMapping(value ="/config", method = RequestMethod.POST)
+ @ResponseStatus(HttpStatus.CREATED)
+ public boolean createConfig(@RequestBody ConfigDTO config, @PathVariable String env) {
+ managementService.setConfig(config);
+ return true;
+ }
+
+ @RequestMapping(value = "/config/{key}", method = RequestMethod.PUT)
+ public boolean updateConfig(@PathVariable String key, @RequestBody ConfigDTO configDTO, @PathVariable String env) {
+ if (key == null) {
+ throw new ParamValidationException("Unknown ID!");
+ }
+ String exitConfig = managementService.getConfig(key);
+ if (exitConfig == null) {
+ throw new ResourceNotFoundException("Unknown ID!"); }
+ return managementService.updateConfig(configDTO);
+ }
+
+ @RequestMapping(value = "/config/{key}", method = RequestMethod.GET)
+ public List<ConfigDTO> getConfig(@PathVariable String key, @PathVariable String env) {
+ String config = managementService.getConfig(key);
+ List<ConfigDTO> configDTOs = new ArrayList<>();
+ if (config == null) {
+ return configDTOs;
+ }
+ ConfigDTO configDTO = new ConfigDTO();
+ configDTO.setKey(key);
+ configDTO.setConfig(config);
+ configDTO.setPath(managementService.getConfigPath(key));
+ if (Constants.GLOBAL_CONFIG.equals(key)) {
+ configDTO.setScope(Constants.GLOBAL_CONFIG);
+ } else if(CLASS_NAME_PATTERN.matcher(key).matches()){
+ configDTO.setScope(Constants.SERVICE);
+ } else {
+ configDTO.setScope(Constants.APPLICATION);
+ }
+ configDTOs.add(configDTO);
+ return configDTOs;
+ }
+
+ @RequestMapping(value = "/config/{key}", method = RequestMethod.DELETE)
+ public boolean deleteConfig(@PathVariable String key, @PathVariable String env) {
+ return managementService.deleteConfig(key);
+ }
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConfigDTO.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConfigDTO.java
new file mode 100644
index 0000000..439fab8
--- /dev/null
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/model/dto/ConfigDTO.java
@@ -0,0 +1,58 @@
+/*
+ * 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.dubbo.admin.model.dto;
+
+public class ConfigDTO {
+
+ private String key;
+ private String config;
+ private String scope;
+ private String path;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getConfig() {
+ return config;
+ }
+
+ public void setConfig(String config) {
+ this.config = config;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/GovernanceConfiguration.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/GovernanceConfiguration.java
index c6ed397..4cae7c8 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/GovernanceConfiguration.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/GovernanceConfiguration.java
@@ -19,6 +19,7 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
+import org.omg.PortableInterceptor.ServerRequestInfo;
@SPI("zookeeper")
@@ -40,4 +41,8 @@
boolean deleteConfig(String group, String key);
+ String getPath(String key);
+
+ String getPath(String group, String key);
+
}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ApolloConfiguration.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ApolloConfiguration.java
index e776f2c..58ce20c 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ApolloConfiguration.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ApolloConfiguration.java
@@ -109,4 +109,14 @@
client.removeItem(appId, env, cluster, group, key, "admin");
return true;
}
+
+ @Override
+ public String getPath(String key) {
+ return null;
+ }
+
+ @Override
+ public String getPath(String group, String key) {
+ return null;
+ }
}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/NoOpConfiguration.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/NoOpConfiguration.java
index 85dca2f..5c4fd18 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/NoOpConfiguration.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/NoOpConfiguration.java
@@ -66,4 +66,14 @@
public boolean deleteConfig(String group, String key) {
return false;
}
+
+ @Override
+ public String getPath(String key) {
+ return null;
+ }
+
+ @Override
+ public String getPath(String group, String key) {
+ return null;
+ }
}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ZookeeperConfiguration.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ZookeeperConfiguration.java
index 0ba847a..a8d3138 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ZookeeperConfiguration.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/registry/config/impl/ZookeeperConfiguration.java
@@ -27,6 +27,8 @@
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.URL;
+import java.security.acl.Group;
+
public class ZookeeperConfiguration implements GovernanceConfiguration {
private static final Logger logger = LoggerFactory.getLogger(ZookeeperConfiguration.class);
@@ -119,6 +121,16 @@
return true;
}
+ @Override
+ public String getPath(String key) {
+ return getNodePath(key, null);
+ }
+
+ @Override
+ public String getPath(String group, String key) {
+ return getNodePath(key, group);
+ }
+
private String getNodePath(String path, String group) {
return toRootDir(group) + path;
}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/ManagementService.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/ManagementService.java
new file mode 100644
index 0000000..9d0a388
--- /dev/null
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/ManagementService.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dubbo.admin.service;
+
+import org.apache.dubbo.admin.model.dto.ConfigDTO;
+
+public interface ManagementService {
+
+
+ void setConfig(ConfigDTO config);
+
+ String getConfig(String key);
+
+ String getConfigPath(String key);
+
+ boolean updateConfig(ConfigDTO configDTO);
+
+ boolean deleteConfig(String key);
+}
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ManagementServiceImpl.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ManagementServiceImpl.java
new file mode 100644
index 0000000..d43e6de
--- /dev/null
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/service/impl/ManagementServiceImpl.java
@@ -0,0 +1,82 @@
+/*
+ * 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.dubbo.admin.service.impl;
+
+import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.model.dto.ConfigDTO;
+import org.apache.dubbo.admin.service.ManagementService;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ManagementServiceImpl extends AbstractService implements ManagementService {
+
+
+ private static String globalConfigPath = "config/dubbo/dubbo.properties";
+
+ @Override
+ public void setConfig(ConfigDTO config) {
+ if (Constants.GLOBAL_CONFIG.equals(config.getKey())) {
+ dynamicConfiguration.setConfig(globalConfigPath, config.getConfig());
+ } else {
+ dynamicConfiguration.setConfig(getPath(config.getKey()), config.getConfig());
+ }
+ }
+
+ @Override
+ public String getConfig(String key) {
+ if (Constants.GLOBAL_CONFIG.equals(key)) {
+ return dynamicConfiguration.getConfig(globalConfigPath);
+ }
+ return dynamicConfiguration.getConfig(getPath(key));
+ }
+
+ @Override
+ public String getConfigPath(String key) {
+ if (Constants.GLOBAL_CONFIG.equals(key)) {
+ return dynamicConfiguration.getPath(globalConfigPath);
+ }
+ return dynamicConfiguration.getPath(getPath(key));
+ }
+
+ @Override
+ public boolean updateConfig(ConfigDTO configDTO) {
+ String key = configDTO.getKey();
+ if (Constants.GLOBAL_CONFIG.equals(key)) {
+ dynamicConfiguration.setConfig(globalConfigPath, configDTO.getConfig());
+ } else {
+ dynamicConfiguration.setConfig(getPath(key), configDTO.getConfig());
+ }
+ return true;
+ }
+
+ @Override
+ public boolean deleteConfig(String key) {
+ if (Constants.GLOBAL_CONFIG.equals(key)) {
+ dynamicConfiguration.deleteConfig(globalConfigPath);
+ } else {
+ dynamicConfiguration.deleteConfig(getPath(key));
+ }
+ return true;
+ }
+
+ private String getPath(String key) {
+ return Constants.CONFIG_KEY + Constants.PATH_SEPARATOR + key + Constants.PATH_SEPARATOR
+ + Constants.DUBBO_PROPERTY;
+ }
+
+}
diff --git a/dubbo-admin-backend/src/main/resources/application.properties b/dubbo-admin-backend/src/main/resources/application.properties
index 429a7c0..c3b0ed5 100644
--- a/dubbo-admin-backend/src/main/resources/application.properties
+++ b/dubbo-admin-backend/src/main/resources/application.properties
@@ -15,8 +15,6 @@
# limitations under the License.
#
-admin.config-center.username=username
-admin.config-center.password=password
admin.config-center=zookeeper://127.0.0.1:2181
admin.registry.group=dubbo
admin.registry.address=zookeeper://127.0.0.1:2181
diff --git a/dubbo-admin-frontend/src/api/menu.js b/dubbo-admin-frontend/src/api/menu.js
index 6f5ccac..05c058c 100644
--- a/dubbo-admin-frontend/src/api/menu.js
+++ b/dubbo-admin-frontend/src/api/menu.js
@@ -32,8 +32,8 @@
},
{ title: 'serviceTest', path: '/test', icon: 'code', badge: 'feature' },
{ title: 'serviceMock', path: '/mock', icon: 'build', badge: 'feature' },
- { title: 'metrics', path: '/metrics', icon: 'show_chart', badge: 'feature' }
-
+ { title: 'metrics', path: '/metrics', icon: 'show_chart', badge: 'feature' },
+ { title: 'configManage', path: '/management', icon: 'build', badge: 'feature' }
]
export default Menu
diff --git a/dubbo-admin-frontend/src/components/Management.vue b/dubbo-admin-frontend/src/components/Management.vue
new file mode 100644
index 0000000..a04a3f2
--- /dev/null
+++ b/dubbo-admin-frontend/src/components/Management.vue
@@ -0,0 +1,293 @@
+<!--
+ - 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.
+ -->
+
+<template>
+ <v-container grid-list-xl fluid >
+ <v-layout row wrap>
+ <v-flex xs12 >
+ <search id="serviceSearch" v-model="filter" :submit="submit" :label="$t('searchDubboConfig')"></search>
+ </v-flex>
+ </v-layout>
+ <v-flex lg12>
+ <v-card>
+ <v-toolbar flat color="transparent" class="elevation-0">
+ <v-toolbar-title><span class="headline">{{$t('searchResult')}}</span></v-toolbar-title>
+ <v-spacer></v-spacer>
+ <v-btn outline color="primary" @click.stop="openDialog" class="mb-2">{{$t('create')}}</v-btn>
+ </v-toolbar>
+
+ <v-card-text class="pa-0" >
+ <v-data-table
+ :headers="headers"
+ :items="dubboConfig"
+ hide-actions
+ class="elevation-0"
+ >
+ <template slot="items" slot-scope="props">
+ <td class="text-xs-left">
+ <v-tooltip bottom >
+ <span slot="activator">
+ {{props.item.key}}
+ </span>
+ <span>{{props.item.path}}</span>
+ </v-tooltip>
+ </td>
+ <td class="text-xs-left">
+ <v-chip
+ :color="getColor(props.item.scope)"
+ text-color="white">
+ {{props.item.scope}}
+ </v-chip>
+ </td>
+ <td class="text-xs-center px-0">
+ <v-tooltip bottom v-for="op in operations" :key="op.id">
+ <v-icon small class="mr-2" slot="activator" @click="itemOperation(op.icon, props.item)">
+ {{op.icon}}
+ </v-icon>
+ <span>{{$t(op.tooltip)}}</span>
+ </v-tooltip>
+ </td>
+ </template>
+ </v-data-table>
+ </v-card-text>
+ </v-card>
+ </v-flex>
+
+ <v-dialog v-model="dialog" width="800px" persistent >
+ <v-card>
+ <v-card-title class="justify-center">
+ <span class="headline">{{$t('createNewDubboConfig')}}</span>
+ </v-card-title>
+ <v-card-text >
+ <v-text-field
+ :label="$t('appName')"
+ :hint="$t('configNameHint')"
+ v-model="key"
+ ></v-text-field>
+
+ <v-subheader class="pa-0 mt-3">{{$t('ruleContent')}}</v-subheader>
+ <ace-editor lang="properties" v-model="rule" :readonly="readonly"></ace-editor>
+
+ </v-card-text>
+ <v-card-actions>
+ <v-spacer></v-spacer>
+ <v-btn flat @click.native="closeDialog">{{$t('close')}}</v-btn>
+ <v-btn depressed color="primary" @click.native="saveItem">{{$t('save')}}</v-btn>
+ </v-card-actions>
+ </v-card>
+ </v-dialog>
+
+ <v-dialog v-model="warn.display" persistent max-width="500px">
+ <v-card>
+ <v-card-title class="headline">{{$t(this.warn.title) + this.warnStatus.id}}</v-card-title>
+ <v-card-text >{{this.warn.text}}</v-card-text>
+ <v-card-actions>
+ <v-spacer></v-spacer>
+ <v-btn flat @click.native="closeWarn">{{$t('cancel')}}</v-btn>
+ <v-btn depressed color="primary" @click.native="deleteItem(warnStatus)">{{$t('confirm')}}</v-btn>
+ </v-card-actions>
+ </v-card>
+ </v-dialog>
+
+ </v-container>
+</template>
+
+<script>
+ import AceEditor from '@/components/public/AceEditor'
+ import Search from '@/components/public/Search'
+ export default {
+ name: 'Management',
+ components: {
+ AceEditor,
+ Search
+ },
+ data: () => ({
+ configCenter: '',
+ rule: '',
+ updateId: '',
+ key: '',
+ filter: '',
+ readonly: false,
+ dialog: false,
+ operations: [
+ {id: 0, icon: 'visibility', tooltip: 'view'},
+ {id: 1, icon: 'edit', tooltip: 'edit'},
+ {id: 3, icon: 'delete', tooltip: 'delete'}
+ ],
+ warn: {
+ display: false,
+ title: '',
+ text: '',
+ status: {}
+ },
+ warnStatus: {},
+ dubboConfig: [],
+ headers: []
+ }),
+ methods: {
+ setHeaders () {
+ this.headers = [
+ {
+ text: this.$t('name'),
+ value: 'name',
+ align: 'left'
+ },
+ {
+ text: this.$t('scope'),
+ value: 'scope',
+ sortable: false
+ },
+ {
+ text: this.$t('operation'),
+ value: 'operation',
+ sortable: false,
+ width: '115px'
+ }
+ ]
+ },
+ itemOperation (icon, item) {
+ switch (icon) {
+ case 'visibility':
+ this.dialog = true
+ this.rule = item.config
+ this.key = item.key
+ this.readonly = true
+ this.updateId = 'close'
+ break
+ case 'edit':
+ this.dialog = true
+ this.rule = item.config
+ this.key = item.key
+ this.updateId = item.key
+ this.readonly = false
+ break
+ case 'delete':
+ this.openWarn('warnDeleteConfig')
+ this.warnStatus.id = item.key
+ }
+ },
+ deleteItem: function (warnStatus) {
+ this.$axios.delete('/manage/config/' + warnStatus.id)
+ .then(response => {
+ if (response.status === 200) {
+ this.warn.display = false
+ this.search(this.filter)
+ this.$notify.success('Delete success')
+ }
+ })
+ },
+ closeDialog: function () {
+ this.rule = ''
+ this.key = ''
+ this.dialog = false
+ this.readonly = false
+ },
+ openDialog: function () {
+ this.dialog = true
+ },
+ openWarn: function (title, text) {
+ this.warn.title = title
+ this.warn.text = text
+ this.warn.display = true
+ },
+ closeWarn: function () {
+ this.warn.title = ''
+ this.warn.text = ''
+ this.warn.display = false
+ },
+ saveItem: function () {
+ let configDTO = {}
+ if (!this.key) {
+ this.$notify.error('Config key is needed')
+ return
+ }
+ configDTO.key = this.key
+ configDTO.config = this.rule
+ let vm = this
+ if (this.updateId) {
+ if (this.updateId === 'close') {
+ this.closeDialog()
+ } else {
+ this.$axios.put('/manage/config/' + this.updateId, configDTO)
+ .then(response => {
+ if (response.status === 200) {
+ vm.search(vm.key)
+ vm.filter = vm.key
+ this.closeDialog()
+ this.$notify.success('Update success')
+ }
+ })
+ }
+ } else {
+ this.$axios.post('/manage/config/', configDTO)
+ .then(response => {
+ if (response.status === 201) {
+ vm.search(vm.key)
+ vm.filter = vm.key
+ vm.closeDialog()
+ vm.$notify.success('Create success')
+ }
+ })
+ }
+ },
+ getColor (scope) {
+ if (scope === 'global') {
+ return 'red'
+ }
+ if (scope === 'application') {
+ return 'green'
+ }
+ if (scope === 'service') {
+ return 'blue'
+ }
+ },
+ submit () {
+ this.filter = this.filter.trim()
+ this.search(this.filter)
+ },
+ search (filter) {
+ this.$axios.get('/manage/config/' + filter)
+ .then(response => {
+ if (response.status === 200) {
+ this.dubboConfig = response.data
+ this.$router.push({path: 'management', query: {key: filter}})
+ }
+ })
+ }
+ },
+ mounted () {
+ this.setHeaders()
+ let query = this.$route.query
+ let filter = null
+ Object.keys(query).forEach(function (key) {
+ if (key === 'key') {
+ filter = query[key]
+ }
+ })
+ if (filter !== null) {
+ this.filter = filter
+ } else {
+ this.filter = 'global'
+ }
+ this.search(this.filter)
+ }
+ }
+</script>
+
+<style scoped>
+
+</style>
diff --git a/dubbo-admin-frontend/src/components/governance/TagRule.vue b/dubbo-admin-frontend/src/components/governance/TagRule.vue
index e776576..dbda2f6 100644
--- a/dubbo-admin-frontend/src/components/governance/TagRule.vue
+++ b/dubbo-admin-frontend/src/components/governance/TagRule.vue
@@ -78,14 +78,14 @@
</v-card>
</v-dialog>
- <v-dialog v-model="warn" persistent max-width="500px">
+ <v-dialog v-model="warn.display" persistent max-width="500px">
<v-card>
- <v-card-title class="headline">{{$t(this.warnTitle)}}</v-card-title>
- <v-card-text >{{this.warnText}}</v-card-text>
+ <v-card-title class="headline">{{$t(this.warn.title)}}</v-card-title>
+ <v-card-text >{{this.warn.text}}</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn flat @click.native="closeWarn">CANCLE</v-btn>
- <v-btn depressed color="primary" @click.native="deleteItem(warnStatus)">CONFIRM</v-btn>
+ <v-btn depressed color="primary" @click.native="deleteItem(warn.status)">{{$t('confirm')}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
@@ -110,12 +110,14 @@
pattern: 'Service',
filter: '',
dialog: false,
- warn: false,
updateId: '',
application: '',
- warnTitle: '',
- warnText: '',
- warnStatus: {},
+ warn: {
+ display: false,
+ title: '',
+ text: '',
+ status: {}
+ },
height: 0,
operations: operations,
tagRoutingRules: [
@@ -179,14 +181,14 @@
this.dialog = true
},
openWarn: function (title, text) {
- this.warnTitle = title
- this.warnText = text
- this.warn = true
+ this.warn.title = title
+ this.warn.text = text
+ this.warn.display = true
},
closeWarn: function () {
- this.warnTitle = ''
- this.warnText = ''
- this.warn = false
+ this.warn.title = ''
+ this.warn.text = ''
+ this.warn.display = false
},
saveItem: function () {
let rule = yaml.safeLoad(this.ruleText)
@@ -248,18 +250,18 @@
break
case 'block':
this.openWarn(' Are you sure to block Tag Rule', 'application: ' + item.application)
- this.warnStatus.operation = 'disable'
- this.warnStatus.id = itemId
+ this.warn.status.operation = 'disable'
+ this.warn.status.id = itemId
break
case 'check_circle_outline':
this.openWarn(' Are you sure to enable Tag Rule', 'application: ' + item.application)
- this.warnStatus.operation = 'enable'
- this.warnStatus.id = itemId
+ this.warn.status.operation = 'enable'
+ this.warn.status.id = itemId
break
case 'delete':
this.openWarn(' Are you sure to Delete Tag Rule', 'application: ' + item.application)
- this.warnStatus.operation = 'delete'
- this.warnStatus.id = itemId
+ this.warn.status.operation = 'delete'
+ this.warn.status.id = itemId
}
},
handleBalance: function (tagRoute, readonly) {
@@ -284,7 +286,7 @@
this.$axios.delete('/rules/route/tag/' + id)
.then(response => {
if (response.status === 200) {
- this.warn = false
+ this.warn.display = false
this.search(this.filter, false)
this.$notify.success('Delete success')
}
@@ -293,7 +295,7 @@
this.$axios.put('/rules/route/tag/disable/' + id)
.then(response => {
if (response.status === 200) {
- this.warn = false
+ this.warn.display = false
this.search(this.filter, false)
this.$notify.success('Disable success')
}
@@ -302,7 +304,7 @@
this.$axios.put('/rules/route/tag/enable/' + id)
.then(response => {
if (response.status === 200) {
- this.warn = false
+ this.warn.display = false
this.search(this.filter, false)
this.$notify.success('Enable success')
}
diff --git a/dubbo-admin-frontend/src/lang/en.js b/dubbo-admin-frontend/src/lang/en.js
index 593206c..2b771d7 100644
--- a/dubbo-admin-frontend/src/lang/en.js
+++ b/dubbo-admin-frontend/src/lang/en.js
@@ -114,5 +114,13 @@
rowsPerPageText: 'Rows per page:'
},
noDataText: 'No data available'
- }
+ },
+ configManage: 'Configuration Management',
+ configCenterAddress: 'ConfigCenter Address',
+ searchDubboConfig: 'Search Dubbo Config',
+ createNewDubboConfig: 'Create New Dubbo Config',
+ scope: 'Scope',
+ name: 'Name',
+ warnDeleteConfig: ' Are you sure to Delete Dubbo Config: ',
+ configNameHint: "Application name the config belongs to, use 'global'(without quotes) for global config"
}
diff --git a/dubbo-admin-frontend/src/lang/zh.js b/dubbo-admin-frontend/src/lang/zh.js
index fc28529..16517d8 100644
--- a/dubbo-admin-frontend/src/lang/zh.js
+++ b/dubbo-admin-frontend/src/lang/zh.js
@@ -114,5 +114,13 @@
rowsPerPageText: '每页行数:'
},
noDataText: '无可用数据'
- }
+ },
+ configManage: '配置管理',
+ configCenterAddress: '配置中心地址',
+ searchDubboConfig: '搜索Dubbo配置',
+ createNewDubboConfig: '新建Dubbo配置',
+ scope: '范围',
+ name: '名称',
+ warnDeleteConfig: ' 是否要删除Dubbo配置: ',
+ configNameHint: '配置所属的应用名, global 表示全局配置'
}
diff --git a/dubbo-admin-frontend/src/router/index.js b/dubbo-admin-frontend/src/router/index.js
index d67bd0c..2ef4da4 100644
--- a/dubbo-admin-frontend/src/router/index.js
+++ b/dubbo-admin-frontend/src/router/index.js
@@ -28,6 +28,7 @@
import ServiceTest from '@/components/test/ServiceTest'
import ServiceMock from '@/components/test/ServiceMock'
import ServiceMetrics from '@/components/metrics/ServiceMetrics'
+import Management from '@/components/Management'
Vue.use(Router)
@@ -86,6 +87,11 @@
path: '/metrics',
name: 'ServiceMetrics',
component: ServiceMetrics
+ },
+ {
+ path: '/management',
+ name: 'Management',
+ component: Management
}
]