You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by ra...@apache.org on 2021/07/29 06:19:21 UTC
[dubbo-admin] branch develop-for-dubbo-3.x updated: [3.0]Add mesh
rule route (#789)
This is an automated email from the ASF dual-hosted git repository.
ranke pushed a commit to branch develop-for-dubbo-3.x
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git
The following commit(s) were added to refs/heads/develop-for-dubbo-3.x by this push:
new a9925f5 [3.0]Add mesh rule route (#789)
a9925f5 is described below
commit a9925f55903caf6193f8207b99d0e601076ae319
Author: haoyann <10...@qq.com>
AuthorDate: Thu Jul 29 14:19:12 2021 +0800
[3.0]Add mesh rule route (#789)
* add mesh rule route
* add mesh rule check
---
.../apache/dubbo/admin/common/util/Constants.java | 2 +-
.../apache/dubbo/admin/common/util/YamlParser.java | 10 +-
.../admin/controller/MeshRouteController.java | 105 +++++
.../apache/dubbo/admin/model/dto/MeshRouteDTO.java | 32 ++
.../dubbo/admin/model/store/mesh/BaseRule.java | 60 +++
.../admin/model/store/mesh/VsDestinationGroup.java | 56 +++
.../mesh/destination/ConnectionPoolSettings.java | 22 ++
.../store/mesh/destination/DestinationRule.java | 41 ++
.../mesh/destination/DestinationRuleSpec.java | 60 +++
.../admin/model/store/mesh/destination/Subset.java | 50 +++
.../model/store/mesh/destination/TCPSettings.java | 25 ++
.../model/store/mesh/destination/TcpKeepalive.java | 26 ++
.../store/mesh/destination/TrafficPolicy.java | 40 ++
.../destination/loadbalance/ConsistentHashLB.java | 22 ++
.../loadbalance/LoadBalancerSettings.java | 48 +++
.../mesh/destination/loadbalance/SimpleLB.java | 26 ++
.../mesh/virtualservice/DubboMatchRequest.java | 131 +++++++
.../store/mesh/virtualservice/DubboRoute.java | 63 +++
.../mesh/virtualservice/DubboRouteDetail.java | 63 +++
.../mesh/virtualservice/VirtualServiceRule.java | 41 ++
.../mesh/virtualservice/VirtualServiceSpec.java | 50 +++
.../destination/DubboDestination.java | 59 +++
.../destination/DubboRouteDestination.java | 40 ++
.../store/mesh/virtualservice/match/BoolMatch.java | 38 ++
.../mesh/virtualservice/match/DoubleMatch.java | 63 +++
.../virtualservice/match/DoubleRangeMatch.java | 53 +++
.../virtualservice/match/DubboAttachmentMatch.java | 76 ++++
.../mesh/virtualservice/match/DubboMethodArg.java | 90 +++++
.../virtualservice/match/DubboMethodMatch.java | 128 +++++++
.../mesh/virtualservice/match/ListBoolMatch.java | 22 ++
.../mesh/virtualservice/match/ListDoubleMatch.java | 43 +++
.../mesh/virtualservice/match/ListStringMatch.java | 44 +++
.../mesh/virtualservice/match/StringMatch.java | 105 +++++
.../dubbo/admin/service/MeshRouteService.java | 56 +++
.../admin/service/impl/MeshRouteServiceImpl.java | 90 +++++
.../admin/controller/MeshRouteControllerTest.java | 141 +++++++
.../src/test/resources/MeshRoute.yml | 58 +++
.../src/test/resources/MeshRouteTest2.yml | 41 ++
dubbo-admin-ui/src/api/menu.js | 3 +-
.../src/components/governance/MeshRule.vue | 422 +++++++++++++++++++++
dubbo-admin-ui/src/lang/en.js | 4 +
dubbo-admin-ui/src/lang/zh.js | 4 +
dubbo-admin-ui/src/router/index.js | 9 +
43 files changed, 2558 insertions(+), 4 deletions(-)
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/Constants.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
index f98a0d9..96e3f24 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/Constants.java
@@ -79,7 +79,7 @@ public class Constants {
public static final String METRICS_PROTOCOL = "metrics.protocol";
public static final Set<String> CONFIGS = new HashSet<>();
public static final String COLON = ":";
-
+ public static final String MESH_RULE_SUFFIX = ".MESHAPPRULE";
static {
CONFIGS.add(WEIGHT);
CONFIGS.add(BALANCING);
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/YamlParser.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/YamlParser.java
index 024097d..81ec3b3 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/YamlParser.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/YamlParser.java
@@ -17,7 +17,7 @@
package org.apache.dubbo.admin.common.util;
-import org.apache.dubbo.common.utils.PojoUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.error.YAMLException;
@@ -30,6 +30,8 @@ import java.util.Map;
public class YamlParser {
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
public static String dumpObject(Object object) {
return new Yaml(new SafeConstructor(), new CustomRepresenter()).dumpAsMap(object);
}
@@ -37,12 +39,16 @@ public class YamlParser {
public static <T> T loadObject(String content, Class<T> type) {
Map<String, Object> map = new Yaml(new SafeConstructor(), new CustomRepresenter()).load(content);
try {
- return (T) PojoUtils.mapToPojo(map, type);
+ return OBJECT_MAPPER.convertValue(map, type);
} catch (Exception e) {
throw new YAMLException(e);
}
}
+ public static Iterable<Object> loadAll(String content) {
+ return new Yaml(new SafeConstructor(), new CustomRepresenter()).loadAll(content);
+ }
+
public static class CustomRepresenter extends Representer {
protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MeshRouteController.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MeshRouteController.java
new file mode 100644
index 0000000..537ca0c
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/controller/MeshRouteController.java
@@ -0,0 +1,105 @@
+/*
+ * 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.annotation.Authority;
+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.MeshRouteDTO;
+import org.apache.dubbo.admin.service.MeshRouteService;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Authority(needLogin = true)
+@RestController
+@RequestMapping("/api/{env}/rules/route/mesh")
+public class MeshRouteController {
+
+ private final MeshRouteService meshRouteService;
+
+ @Autowired
+ public MeshRouteController(MeshRouteService meshRouteService) {
+ this.meshRouteService = meshRouteService;
+ }
+
+ @RequestMapping(method = RequestMethod.POST)
+ @ResponseStatus(HttpStatus.CREATED)
+ public boolean createMeshRoute(@RequestBody MeshRouteDTO meshRoute, @PathVariable String env) {
+ String app = meshRoute.getApplication();
+ if (StringUtils.isEmpty(app)) {
+ throw new ParamValidationException("app is Empty!");
+ }
+ // todo check appName
+
+ return meshRouteService.createMeshRule(meshRoute);
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public boolean updateRule(@PathVariable String id, @RequestBody MeshRouteDTO meshRoute, @PathVariable String env) {
+ id = id.replace(Constants.ANY_VALUE, Constants.PATH_SEPARATOR);
+ if (meshRouteService.findMeshRoute(id) == null) {
+ throw new ResourceNotFoundException("can not find mesh route, Id: " + id);
+ }
+ meshRoute.setId(id);
+ return meshRouteService.updateMeshRule(meshRoute);
+ }
+
+ @RequestMapping(method = RequestMethod.GET)
+ public List<MeshRouteDTO> searchRoutes(@RequestParam String application, @PathVariable String env) {
+ if (StringUtils.isBlank(application)) {
+ throw new ParamValidationException("application is required.");
+ }
+ List<MeshRouteDTO> result = new ArrayList<>();
+
+ MeshRouteDTO meshRoute = meshRouteService.findMeshRoute(application);
+ if (meshRoute != null) {
+ result.add(meshRoute);
+ }
+ return result;
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+ public MeshRouteDTO detailRoute(@PathVariable String id, @PathVariable String env) {
+ id = id.replace(Constants.ANY_VALUE, Constants.PATH_SEPARATOR);
+ MeshRouteDTO meshRoute = meshRouteService.findMeshRoute(id);
+ if (meshRoute == null) {
+ throw new ResourceNotFoundException("Unknown ID!");
+ }
+ return meshRoute;
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+ public boolean deleteRoute(@PathVariable String id, @PathVariable String env) {
+ id = id.replace(Constants.ANY_VALUE, Constants.PATH_SEPARATOR);
+ return meshRouteService.deleteMeshRule(id);
+ }
+
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/dto/MeshRouteDTO.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/dto/MeshRouteDTO.java
new file mode 100644
index 0000000..349c3c0
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/dto/MeshRouteDTO.java
@@ -0,0 +1,32 @@
+/*
+ * 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 MeshRouteDTO extends BaseDTO{
+
+ private String meshRule;
+
+ public String getMeshRule() {
+ return meshRule;
+ }
+
+ public void setMeshRule(String meshRule) {
+ this.meshRule = meshRule;
+ }
+
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/BaseRule.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/BaseRule.java
new file mode 100644
index 0000000..94e7afd
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/BaseRule.java
@@ -0,0 +1,60 @@
+/*
+ * 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.store.mesh;
+
+import java.util.Map;
+
+
+public class BaseRule {
+ private String apiVersion;
+ private String kind;
+ private Map<String,String> metadata;
+
+ public String getApiVersion() {
+ return apiVersion;
+ }
+
+ public void setApiVersion(String apiVersion) {
+ this.apiVersion = apiVersion;
+ }
+
+ public String getKind() {
+ return kind;
+ }
+
+ public void setKind(String kind) {
+ this.kind = kind;
+ }
+
+ public Map<String, String> getMetadata() {
+ return metadata;
+ }
+
+ public void setMetadata(Map<String, String> metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public String toString() {
+ return "BaseRule{" +
+ "apiVersion='" + apiVersion + '\'' +
+ ", kind='" + kind + '\'' +
+ ", metadata=" + metadata +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/VsDestinationGroup.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/VsDestinationGroup.java
new file mode 100644
index 0000000..8c99863
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/VsDestinationGroup.java
@@ -0,0 +1,56 @@
+/*
+ * 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.store.mesh;
+
+
+import org.apache.dubbo.admin.model.store.mesh.destination.DestinationRule;
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.VirtualServiceRule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class VsDestinationGroup {
+ private String appName;
+ private List<VirtualServiceRule> virtualServiceRuleList = new ArrayList<>();
+ private List<DestinationRule> destinationRuleList = new ArrayList<>();
+
+ public String getAppName() {
+ return appName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public List<VirtualServiceRule> getVirtualServiceRuleList() {
+ return virtualServiceRuleList;
+ }
+
+ public void setVirtualServiceRuleList(List<VirtualServiceRule> virtualServiceRuleList) {
+ this.virtualServiceRuleList = virtualServiceRuleList;
+ }
+
+ public List<DestinationRule> getDestinationRuleList() {
+ return destinationRuleList;
+ }
+
+ public void setDestinationRuleList(List<DestinationRule> destinationRuleList) {
+ this.destinationRuleList = destinationRuleList;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/ConnectionPoolSettings.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/ConnectionPoolSettings.java
new file mode 100644
index 0000000..71a5c43
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/ConnectionPoolSettings.java
@@ -0,0 +1,22 @@
+/*
+ * 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.store.mesh.destination;
+
+
+public class ConnectionPoolSettings {
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/DestinationRule.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/DestinationRule.java
new file mode 100644
index 0000000..9b0d8c6
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/DestinationRule.java
@@ -0,0 +1,41 @@
+/*
+ * 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.store.mesh.destination;
+
+
+import org.apache.dubbo.admin.model.store.mesh.BaseRule;
+
+public class DestinationRule extends BaseRule {
+ private DestinationRuleSpec spec;
+
+ public DestinationRuleSpec getSpec() {
+ return spec;
+ }
+
+ public void setSpec(DestinationRuleSpec spec) {
+ this.spec = spec;
+ }
+
+ @Override
+ public String toString() {
+ return "DestinationRule{" +
+ "base=" + super.toString() +
+ ", spec=" + spec +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/DestinationRuleSpec.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/DestinationRuleSpec.java
new file mode 100644
index 0000000..470b7c4
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/DestinationRuleSpec.java
@@ -0,0 +1,60 @@
+/*
+ * 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.store.mesh.destination;
+
+import java.util.List;
+
+
+public class DestinationRuleSpec {
+ private String host;
+ private List<Subset> subsets;
+ private TrafficPolicy trafficPolicy;
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public List<Subset> getSubsets() {
+ return subsets;
+ }
+
+ public void setSubsets(List<Subset> subsets) {
+ this.subsets = subsets;
+ }
+
+ public TrafficPolicy getTrafficPolicy() {
+ return trafficPolicy;
+ }
+
+ public void setTrafficPolicy(TrafficPolicy trafficPolicy) {
+ this.trafficPolicy = trafficPolicy;
+ }
+
+ @Override
+ public String toString() {
+ return "DestinationRuleSpec{" +
+ "host='" + host + '\'' +
+ ", subsets=" + subsets +
+ ", trafficPolicy=" + trafficPolicy +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/Subset.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/Subset.java
new file mode 100644
index 0000000..66b6fa4
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/Subset.java
@@ -0,0 +1,50 @@
+/*
+ * 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.store.mesh.destination;
+
+import java.util.Map;
+
+
+public class Subset {
+ private String name;
+ private Map<String, String> labels;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Map<String, String> getLabels() {
+ return labels;
+ }
+
+ public void setLabels(Map<String, String> labels) {
+ this.labels = labels;
+ }
+
+ @Override
+ public String toString() {
+ return "Subset{" +
+ "name='" + name + '\'' +
+ ", labels=" + labels +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TCPSettings.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TCPSettings.java
new file mode 100644
index 0000000..1cc05ce
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TCPSettings.java
@@ -0,0 +1,25 @@
+/*
+ * 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.store.mesh.destination;
+
+
+public class TCPSettings {
+ private int maxConnections;
+ private int connectTimeout;
+ private TcpKeepalive tcpKeepalive;
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TcpKeepalive.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TcpKeepalive.java
new file mode 100644
index 0000000..aa48bf6
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TcpKeepalive.java
@@ -0,0 +1,26 @@
+/*
+ * 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.store.mesh.destination;
+
+
+public class TcpKeepalive {
+ private int probes;
+ private int time;
+ private int interval;
+
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TrafficPolicy.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TrafficPolicy.java
new file mode 100644
index 0000000..bda74d6
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/TrafficPolicy.java
@@ -0,0 +1,40 @@
+/*
+ * 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.store.mesh.destination;
+
+
+import org.apache.dubbo.admin.model.store.mesh.destination.loadbalance.LoadBalancerSettings;
+
+public class TrafficPolicy {
+ private LoadBalancerSettings loadBalancer;
+
+ public LoadBalancerSettings getLoadBalancer() {
+ return loadBalancer;
+ }
+
+ public void setLoadBalancer(LoadBalancerSettings loadBalancer) {
+ this.loadBalancer = loadBalancer;
+ }
+
+ @Override
+ public String toString() {
+ return "TrafficPolicy{" +
+ "loadBalancer=" + loadBalancer +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/ConsistentHashLB.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/ConsistentHashLB.java
new file mode 100644
index 0000000..e0c11e4
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/ConsistentHashLB.java
@@ -0,0 +1,22 @@
+/*
+ * 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.store.mesh.destination.loadbalance;
+
+
+public class ConsistentHashLB {
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/LoadBalancerSettings.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/LoadBalancerSettings.java
new file mode 100644
index 0000000..5a5a1ec
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/LoadBalancerSettings.java
@@ -0,0 +1,48 @@
+/*
+ * 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.store.mesh.destination.loadbalance;
+
+
+public class LoadBalancerSettings {
+ private SimpleLB simple;
+ private ConsistentHashLB consistentHash;
+
+ public SimpleLB getSimple() {
+ return simple;
+ }
+
+ public void setSimple(SimpleLB simple) {
+ this.simple = simple;
+ }
+
+ public ConsistentHashLB getConsistentHash() {
+ return consistentHash;
+ }
+
+ public void setConsistentHash(ConsistentHashLB consistentHash) {
+ this.consistentHash = consistentHash;
+ }
+
+ @Override
+ public String toString() {
+ return "LoadBalancerSettings{" +
+ "simple=" + simple +
+ ", consistentHash=" + consistentHash +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/SimpleLB.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/SimpleLB.java
new file mode 100644
index 0000000..b8b13ec
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/destination/loadbalance/SimpleLB.java
@@ -0,0 +1,26 @@
+/*
+ * 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.store.mesh.destination.loadbalance;
+
+
+public enum SimpleLB {
+ ROUND_ROBIN,
+ LEAST_CONN,
+ RANDOM,
+ PASSTHROUGH
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboMatchRequest.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboMatchRequest.java
new file mode 100644
index 0000000..59dcd3c
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboMatchRequest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.store.mesh.virtualservice;
+
+
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.DoubleMatch;
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.DubboAttachmentMatch;
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.DubboMethodMatch;
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.StringMatch;
+
+import java.util.Map;
+
+
+public class DubboMatchRequest {
+ private String name;
+ private DubboMethodMatch method;
+ private Map<String, String> sourceLabels;
+ private DubboAttachmentMatch attachments;
+ private Map<String, StringMatch> headers;
+ private DoubleMatch threshold;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public DubboMethodMatch getMethod() {
+ return method;
+ }
+
+ public void setMethod(DubboMethodMatch method) {
+ this.method = method;
+ }
+
+ public Map<String, String> getSourceLabels() {
+ return sourceLabels;
+ }
+
+ public void setSourceLabels(Map<String, String> sourceLabels) {
+ this.sourceLabels = sourceLabels;
+ }
+
+ public DubboAttachmentMatch getAttachments() {
+ return attachments;
+ }
+
+ public void setAttachments(DubboAttachmentMatch attachments) {
+ this.attachments = attachments;
+ }
+
+ public Map<String, StringMatch> getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(Map<String, StringMatch> headers) {
+ this.headers = headers;
+ }
+
+ public DoubleMatch getThreshold() {
+ return threshold;
+ }
+
+ public void setThreshold(DoubleMatch threshold) {
+ this.threshold = threshold;
+ }
+
+
+ public static boolean isMatch(DubboMatchRequest dubboMatchRequest,
+ String methodName, String[] parameterTypeList, Object[] parameters,
+ Map<String, String> sourceLabels,
+ Map<String, String> eagleeyeContext, Map<String, String> dubboContext,
+ Map<String, String> headers
+ ) {
+ if (dubboMatchRequest.getMethod() != null) {
+ if (!DubboMethodMatch.isMatch(dubboMatchRequest.getMethod(), methodName, parameterTypeList, parameters)) {
+ return false;
+ }
+ }
+
+ if (dubboMatchRequest.getSourceLabels() != null) {
+ for (Map.Entry<String, String> entry : dubboMatchRequest.getSourceLabels().entrySet()) {
+ String value = sourceLabels.get(entry.getKey());
+ if (value == null || !entry.getValue().equals(value)) {
+ return false;
+ }
+ }
+ }
+
+ if (dubboMatchRequest.getAttachments() != null) {
+ if (!DubboAttachmentMatch.isMatch(dubboMatchRequest.getAttachments(),eagleeyeContext,dubboContext)){
+ return false;
+ }
+ }
+
+ //TODO headers
+
+
+ return true;
+
+ }
+
+ @Override
+ public String toString() {
+ return "DubboMatchRequest{" +
+ "name='" + name + '\'' +
+ ", method=" + method +
+ ", sourceLabels=" + sourceLabels +
+ ", attachments=" + attachments +
+ ", headers=" + headers +
+ ", threshold=" + threshold +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboRoute.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboRoute.java
new file mode 100644
index 0000000..9747b6b
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboRoute.java
@@ -0,0 +1,63 @@
+/*
+ * 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.store.mesh.virtualservice;
+
+
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.match.StringMatch;
+
+import java.util.List;
+
+
+public class DubboRoute {
+ private String name;
+ private List<StringMatch> services;
+ private List<DubboRouteDetail> routedetail;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<StringMatch> getServices() {
+ return services;
+ }
+
+ public void setServices(List<StringMatch> services) {
+ this.services = services;
+ }
+
+ public List<DubboRouteDetail> getRoutedetail() {
+ return routedetail;
+ }
+
+ public void setRoutedetail(List<DubboRouteDetail> routedetail) {
+ this.routedetail = routedetail;
+ }
+
+ @Override
+ public String toString() {
+ return "DubboRoute{" +
+ "name='" + name + '\'' +
+ ", services=" + services +
+ ", routedetail=" + routedetail +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboRouteDetail.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboRouteDetail.java
new file mode 100644
index 0000000..1b576d5
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/DubboRouteDetail.java
@@ -0,0 +1,63 @@
+/*
+ * 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.store.mesh.virtualservice;
+
+
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.destination.DubboRouteDestination;
+
+import java.util.List;
+
+
+public class DubboRouteDetail {
+ private String name;
+ private List<DubboMatchRequest> match;
+ private List<DubboRouteDestination> route;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<DubboMatchRequest> getMatch() {
+ return match;
+ }
+
+ public void setMatch(List<DubboMatchRequest> match) {
+ this.match = match;
+ }
+
+ public List<DubboRouteDestination> getRoute() {
+ return route;
+ }
+
+ public void setRoute(List<DubboRouteDestination> route) {
+ this.route = route;
+ }
+
+ @Override
+ public String toString() {
+ return "DubboRouteDetail{" +
+ "name='" + name + '\'' +
+ ", match=" + match +
+ ", route=" + route +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/VirtualServiceRule.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/VirtualServiceRule.java
new file mode 100644
index 0000000..c5798d8
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/VirtualServiceRule.java
@@ -0,0 +1,41 @@
+/*
+ * 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.store.mesh.virtualservice;
+
+
+import org.apache.dubbo.admin.model.store.mesh.BaseRule;
+
+public class VirtualServiceRule extends BaseRule {
+ private VirtualServiceSpec spec;
+
+ public VirtualServiceSpec getSpec() {
+ return spec;
+ }
+
+ public void setSpec(VirtualServiceSpec spec) {
+ this.spec = spec;
+ }
+
+ @Override
+ public String toString() {
+ return "VirtualServiceRule{" +
+ "base=" + super.toString() +
+ ", spec=" + spec +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/VirtualServiceSpec.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/VirtualServiceSpec.java
new file mode 100644
index 0000000..c4eab8d
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/VirtualServiceSpec.java
@@ -0,0 +1,50 @@
+/*
+ * 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.store.mesh.virtualservice;
+
+import java.util.List;
+
+
+public class VirtualServiceSpec {
+ private List<String> hosts;
+ private List<DubboRoute> dubbo;
+
+ public List<String> getHosts() {
+ return hosts;
+ }
+
+ public void setHosts(List<String> hosts) {
+ this.hosts = hosts;
+ }
+
+ public List<DubboRoute> getDubbo() {
+ return dubbo;
+ }
+
+ public void setDubbo(List<DubboRoute> dubbo) {
+ this.dubbo = dubbo;
+ }
+
+ @Override
+ public String toString() {
+ return "VirtualServiceSpec{" +
+ "hosts=" + hosts +
+ ", dubbo=" + dubbo +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/destination/DubboDestination.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/destination/DubboDestination.java
new file mode 100644
index 0000000..781308e
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/destination/DubboDestination.java
@@ -0,0 +1,59 @@
+/*
+ * 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.store.mesh.virtualservice.destination;
+
+
+public class DubboDestination {
+ private String host;
+ private String subset;
+ private int port;
+ private DubboRouteDestination fallback;
+
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public String getSubset() {
+ return subset;
+ }
+
+ public void setSubset(String subset) {
+ this.subset = subset;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public DubboRouteDestination getFallback() {
+ return fallback;
+ }
+
+ public void setFallback(DubboRouteDestination fallback) {
+ this.fallback = fallback;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/destination/DubboRouteDestination.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/destination/DubboRouteDestination.java
new file mode 100644
index 0000000..95ede77
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/destination/DubboRouteDestination.java
@@ -0,0 +1,40 @@
+/*
+ * 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.store.mesh.virtualservice.destination;
+
+
+public class DubboRouteDestination {
+ private DubboDestination destination;
+ private int weight;
+
+ public DubboDestination getDestination() {
+ return destination;
+ }
+
+ public void setDestination(DubboDestination destination) {
+ this.destination = destination;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/BoolMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/BoolMatch.java
new file mode 100644
index 0000000..d354157
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/BoolMatch.java
@@ -0,0 +1,38 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+
+public class BoolMatch {
+ private Boolean exact;
+
+ public Boolean getExact() {
+ return exact;
+ }
+
+ public void setExact(Boolean exact) {
+ this.exact = exact;
+ }
+
+ public static boolean isMatch(BoolMatch boolMatch,boolean input){
+ if (boolMatch.getExact() != null){
+ return input == boolMatch.getExact();
+ }
+ return false;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DoubleMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DoubleMatch.java
new file mode 100644
index 0000000..89ab4d6
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DoubleMatch.java
@@ -0,0 +1,63 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+
+public class DoubleMatch {
+ private Double exact;
+ private DoubleRangeMatch range;
+ private Double mod;
+
+ public Double getExact() {
+ return exact;
+ }
+
+ public void setExact(Double exact) {
+ this.exact = exact;
+ }
+
+ public DoubleRangeMatch getRange() {
+ return range;
+ }
+
+ public void setRange(DoubleRangeMatch range) {
+ this.range = range;
+ }
+
+ public Double getMod() {
+ return mod;
+ }
+
+ public void setMod(Double mod) {
+ this.mod = mod;
+ }
+
+
+ public static boolean isMatch(DoubleMatch doubleMatch, Double input) {
+ if (doubleMatch.getExact() != null && doubleMatch.getMod() == null) {
+ return input.equals(doubleMatch.getExact());
+ } else if (doubleMatch.getRange() != null) {
+ return DoubleRangeMatch.isMatch(doubleMatch.getRange(), input);
+ } else if (doubleMatch.getExact() != null && doubleMatch.getMod() != null) {
+ Double result = input % doubleMatch.getMod();
+ return result.equals(doubleMatch.getExact());
+ }
+
+ return false;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DoubleRangeMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DoubleRangeMatch.java
new file mode 100644
index 0000000..00d09db
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DoubleRangeMatch.java
@@ -0,0 +1,53 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+
+public class DoubleRangeMatch {
+ private Double start;
+ private Double end;
+
+ public Double getStart() {
+ return start;
+ }
+
+ public void setStart(Double start) {
+ this.start = start;
+ }
+
+ public Double getEnd() {
+ return end;
+ }
+
+ public void setEnd(Double end) {
+ this.end = end;
+ }
+
+
+ public static boolean isMatch(DoubleRangeMatch doubleRangeMatch, Double input) {
+ if (doubleRangeMatch.getStart() != null && doubleRangeMatch.getEnd() != null) {
+ return input.compareTo(doubleRangeMatch.getStart()) >= 0 && input.compareTo(doubleRangeMatch.getEnd()) < 0;
+ } else if (doubleRangeMatch.getStart() != null) {
+ return input.compareTo(doubleRangeMatch.getStart()) >= 0;
+ } else if (doubleRangeMatch.getEnd() != null) {
+ return input.compareTo(doubleRangeMatch.getEnd()) < 0;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboAttachmentMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboAttachmentMatch.java
new file mode 100644
index 0000000..37f1da4
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboAttachmentMatch.java
@@ -0,0 +1,76 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+import java.util.Map;
+
+
+public class DubboAttachmentMatch {
+ private Map<String, StringMatch> eagleeyecontext;
+ private Map<String, StringMatch> dubbocontext;
+
+ public Map<String, StringMatch> getEagleeyecontext() {
+ return eagleeyecontext;
+ }
+
+ public void setEagleeyecontext(Map<String, StringMatch> eagleeyecontext) {
+ this.eagleeyecontext = eagleeyecontext;
+ }
+
+ public Map<String, StringMatch> getDubbocontext() {
+ return dubbocontext;
+ }
+
+ public void setDubbocontext(Map<String, StringMatch> dubbocontext) {
+ this.dubbocontext = dubbocontext;
+ }
+
+ public static boolean isMatch(DubboAttachmentMatch dubboAttachmentMatch, Map<String, String> eagleeyeContext, Map<String, String> dubboContext) {
+ if (dubboAttachmentMatch.getDubbocontext() != null) {
+ for (Map.Entry<String, StringMatch> stringStringMatchEntry : dubboAttachmentMatch.getDubbocontext().entrySet()) {
+ String key = stringStringMatchEntry.getKey();
+ StringMatch stringMatch = stringStringMatchEntry.getValue();
+
+ String dubboContextValue = dubboContext.get(key);
+ if (dubboContextValue == null) {
+ return false;
+ }
+ if (!StringMatch.isMatch(stringMatch, dubboContextValue)) {
+ return false;
+ }
+ }
+ }
+
+ if (dubboAttachmentMatch.getEagleeyecontext() != null) {
+ for (Map.Entry<String, StringMatch> stringStringMatchEntry : dubboAttachmentMatch.getEagleeyecontext().entrySet()) {
+ String key = stringStringMatchEntry.getKey();
+ StringMatch stringMatch = stringStringMatchEntry.getValue();
+
+ String eagleeyeContextValue = eagleeyeContext.get(key);
+ if (eagleeyeContextValue == null) {
+ return false;
+ }
+ if (!StringMatch.isMatch(stringMatch, eagleeyeContextValue)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboMethodArg.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboMethodArg.java
new file mode 100644
index 0000000..8e0f991
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboMethodArg.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.model.store.mesh.virtualservice.match;
+
+
+public class DubboMethodArg {
+ private int index;
+ private String type;
+ private ListStringMatch str_value;
+ private ListDoubleMatch num_value;
+ private BoolMatch bool_value;
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public ListStringMatch getStr_value() {
+ return str_value;
+ }
+
+ public void setStr_value(ListStringMatch str_value) {
+ this.str_value = str_value;
+ }
+
+ public ListDoubleMatch getNum_value() {
+ return num_value;
+ }
+
+ public void setNum_value(ListDoubleMatch num_value) {
+ this.num_value = num_value;
+ }
+
+ public BoolMatch getBool_value() {
+ return bool_value;
+ }
+
+ public void setBool_value(BoolMatch bool_value) {
+ this.bool_value = bool_value;
+ }
+
+ public static boolean isMatch(DubboMethodArg dubboMethodArg, Object input) {
+
+ if (dubboMethodArg.getStr_value() != null) {
+ return ListStringMatch.isMatch(dubboMethodArg.getStr_value(), (String) input);
+ } else if (dubboMethodArg.getNum_value() != null) {
+ return ListDoubleMatch.isMatch(dubboMethodArg.getNum_value(), Double.valueOf(input.toString()));
+ } else if (dubboMethodArg.getBool_value() != null) {
+ return BoolMatch.isMatch(dubboMethodArg.getBool_value(), (Boolean) input);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "DubboMethodArg{" +
+ "index=" + index +
+ ", type='" + type + '\'' +
+ ", str_value=" + str_value +
+ ", num_value=" + num_value +
+ ", bool_value=" + bool_value +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboMethodMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboMethodMatch.java
new file mode 100644
index 0000000..c448895
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/DubboMethodMatch.java
@@ -0,0 +1,128 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+import java.util.List;
+import java.util.Map;
+
+
+public class DubboMethodMatch {
+ private StringMatch name_match;
+ private Integer argc;
+ private List<DubboMethodArg> args;
+ private List<StringMatch> argp;
+ private Map<String, StringMatch> headers;
+
+ public StringMatch getName_match() {
+ return name_match;
+ }
+
+ public void setName_match(StringMatch name_match) {
+ this.name_match = name_match;
+ }
+
+ public Integer getArgc() {
+ return argc;
+ }
+
+ public void setArgc(Integer argc) {
+ this.argc = argc;
+ }
+
+ public List<DubboMethodArg> getArgs() {
+ return args;
+ }
+
+ public void setArgs(List<DubboMethodArg> args) {
+ this.args = args;
+ }
+
+ public List<StringMatch> getArgp() {
+ return argp;
+ }
+
+ public void setArgp(List<StringMatch> argp) {
+ this.argp = argp;
+ }
+
+ public Map<String, StringMatch> getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(Map<String, StringMatch> headers) {
+ this.headers = headers;
+ }
+
+ public static boolean isMatch(DubboMethodMatch dubboMethodMatch, String methodName, String[] parameterTypeList, Object[] parameters) {
+ StringMatch nameMatch = dubboMethodMatch.getName_match();
+ if (nameMatch != null && !StringMatch.isMatch(nameMatch, methodName)) {
+ return false;
+ }
+
+ Integer argc = dubboMethodMatch.getArgc();
+ if (argc != null &&
+ ((argc != 0 && (parameters == null || parameters.length == 0)) || (argc != parameters.length))) {
+ return false;
+ }
+ List<StringMatch> argp = dubboMethodMatch.getArgp();
+ if (argp != null) {
+ if (((parameterTypeList == null || parameterTypeList.length == 0) && argp.size() > 0)
+ || (argp.size() != parameterTypeList.length)) {
+ return false;
+ }
+
+ for (int index = 0; index < argp.size(); index++) {
+ if (!StringMatch.isMatch(argp.get(index), parameterTypeList[index])) {
+ return false;
+ }
+ }
+ }
+
+ List<DubboMethodArg> args = dubboMethodMatch.getArgs();
+
+ if (args != null && args.size() > 0) {
+ if (parameters == null || parameters.length == 0) {
+ return false;
+ }
+
+ for (DubboMethodArg dubboMethodArg : args) {
+ int index = dubboMethodArg.getIndex();
+ if (index >= parameters.length) {
+ throw new IndexOutOfBoundsException("DubboMethodArg index >= parameters.length");
+ }
+ if (!DubboMethodArg.isMatch(dubboMethodArg, parameters[index])) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "DubboMethodMatch{" +
+ "name_match=" + name_match +
+ ", argc=" + argc +
+ ", args=" + args +
+ ", argp=" + argp +
+ ", headers=" + headers +
+ '}';
+ }
+}
+
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListBoolMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListBoolMatch.java
new file mode 100644
index 0000000..b3289e2
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListBoolMatch.java
@@ -0,0 +1,22 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+
+public class ListBoolMatch {
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListDoubleMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListDoubleMatch.java
new file mode 100644
index 0000000..51c4b44
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListDoubleMatch.java
@@ -0,0 +1,43 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+import java.util.List;
+
+
+public class ListDoubleMatch {
+ private List<DoubleMatch> oneof;
+
+ public List<DoubleMatch> getOneof() {
+ return oneof;
+ }
+
+ public void setOneof(List<DoubleMatch> oneof) {
+ this.oneof = oneof;
+ }
+
+ public static boolean isMatch(ListDoubleMatch listDoubleMatch, Double input) {
+
+ for (DoubleMatch doubleMatch : listDoubleMatch.getOneof()) {
+ if (DoubleMatch.isMatch(doubleMatch, input)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListStringMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListStringMatch.java
new file mode 100644
index 0000000..d8f935f
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/ListStringMatch.java
@@ -0,0 +1,44 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+import java.util.List;
+
+
+public class ListStringMatch {
+ private List<StringMatch> oneof;
+
+ public List<StringMatch> getOneof() {
+ return oneof;
+ }
+
+ public void setOneof(List<StringMatch> oneof) {
+ this.oneof = oneof;
+ }
+
+
+ public static boolean isMatch(ListStringMatch listStringMatch, String input) {
+
+ for (StringMatch stringMatch : listStringMatch.getOneof()) {
+ if (StringMatch.isMatch(stringMatch, input)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/StringMatch.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/StringMatch.java
new file mode 100644
index 0000000..5cd7465
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/store/mesh/virtualservice/match/StringMatch.java
@@ -0,0 +1,105 @@
+/*
+ * 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.store.mesh.virtualservice.match;
+
+
+public class StringMatch {
+ private String exact;
+ private String prefix;
+ private String regex;
+ private String noempty;
+ private String empty;
+
+
+ public String getExact() {
+ return exact;
+ }
+
+ public void setExact(String exact) {
+ this.exact = exact;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getRegex() {
+ return regex;
+ }
+
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
+
+ public String getNoempty() {
+ return noempty;
+ }
+
+ public void setNoempty(String noempty) {
+ this.noempty = noempty;
+ }
+
+ public String getEmpty() {
+ return empty;
+ }
+
+ public void setEmpty(String empty) {
+ this.empty = empty;
+ }
+
+
+ public static boolean isMatch(StringMatch stringMatch, String input) {
+ if (stringMatch.getExact() != null && input != null) {
+ if (input.equals(stringMatch.getExact())) {
+ return true;
+ }
+ } else if (stringMatch.getPrefix() != null && input != null) {
+ if (input.startsWith(stringMatch.getPrefix())) {
+ return true;
+ }
+ } else if (stringMatch.getRegex() != null && input != null) {
+ if (input.matches(stringMatch.getRegex())) {
+ return true;
+ }
+ } else if (stringMatch.getEmpty() != null) {
+ return input == null || "".equals(input);
+ } else if (stringMatch.getNoempty() != null) {
+ return input != null && input.length() > 0;
+ } else {
+ return false;
+ }
+
+ return false;
+ }
+
+
+ @Override
+ public String toString() {
+ return "StringMatch{" +
+ "exact='" + exact + '\'' +
+ ", prefix='" + prefix + '\'' +
+ ", regex='" + regex + '\'' +
+ ", noempty='" + noempty + '\'' +
+ ", empty='" + empty + '\'' +
+ '}';
+ }
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/MeshRouteService.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/MeshRouteService.java
new file mode 100644
index 0000000..708dd7e
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/MeshRouteService.java
@@ -0,0 +1,56 @@
+/*
+ * 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.MeshRouteDTO;
+
+public interface MeshRouteService {
+
+ /**
+ * create mesh rule route
+ *
+ * @param meshRoute dto
+ * @return success
+ */
+ boolean createMeshRule(MeshRouteDTO meshRoute);
+
+ /**
+ * update mesh rule route
+ *
+ * @param meshRoute dto
+ * @return success
+ */
+ boolean updateMeshRule(MeshRouteDTO meshRoute);
+
+ /**
+ * delete mesh rule
+ *
+ * @param id id
+ * @return success
+ */
+ boolean deleteMeshRule(String id);
+
+ /**
+ * find mesh rule by id
+ *
+ * @param id id
+ * @return dto
+ */
+ MeshRouteDTO findMeshRoute(String id);
+
+}
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/MeshRouteServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/MeshRouteServiceImpl.java
new file mode 100644
index 0000000..b234eaf
--- /dev/null
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/MeshRouteServiceImpl.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.service.impl;
+
+import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.common.util.ConvertUtil;
+import org.apache.dubbo.admin.common.util.YamlParser;
+import org.apache.dubbo.admin.model.dto.MeshRouteDTO;
+import org.apache.dubbo.admin.model.store.mesh.destination.DestinationRule;
+import org.apache.dubbo.admin.model.store.mesh.virtualservice.VirtualServiceRule;
+import org.apache.dubbo.admin.service.MeshRouteService;
+
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+
+@Service
+public class MeshRouteServiceImpl extends AbstractService implements MeshRouteService {
+
+ @Override
+ public boolean createMeshRule(MeshRouteDTO meshRoute) {
+ String routeRule = meshRoute.getMeshRule();
+ checkMeshRule(routeRule);
+ String id = ConvertUtil.getIdFromDTO(meshRoute);
+ String path = getPath(id);
+ dynamicConfiguration.setConfig(path, routeRule);
+ return true;
+ }
+
+ @Override
+ public boolean updateMeshRule(MeshRouteDTO meshRoute) {
+ String id = ConvertUtil.getIdFromDTO(meshRoute);
+ String path = getPath(id);
+ checkMeshRule(meshRoute.getMeshRule());
+ dynamicConfiguration.setConfig(path, meshRoute.getMeshRule());
+ return true;
+ }
+
+ private void checkMeshRule(String meshRule) {
+ Iterable<Object> objectIterable = YamlParser.loadAll(meshRule);
+ for (Object result : objectIterable) {
+ Map resultMap = (Map) result;
+ if ("DestinationRule".equals(resultMap.get("kind"))) {
+ YamlParser.loadObject(YamlParser.dumpObject(result), DestinationRule.class);
+ } else if ("VirtualService".equals(resultMap.get("kind"))) {
+ YamlParser.loadObject(YamlParser.dumpObject(result), VirtualServiceRule.class);
+ }
+ }
+ }
+
+ @Override
+ public boolean deleteMeshRule(String id) {
+ String path = getPath(id);
+ return dynamicConfiguration.deleteConfig(path);
+ }
+
+ @Override
+ public MeshRouteDTO findMeshRoute(String id) {
+ String path = getPath(id);
+ String rule = dynamicConfiguration.getConfig(path);
+ if (rule == null) {
+ return null;
+ }
+ MeshRouteDTO meshRoute = new MeshRouteDTO();
+ meshRoute.setApplication(id);
+ meshRoute.setMeshRule(rule);
+ return meshRoute;
+ }
+
+ private String getPath(String id) {
+ return Constants.CONFIG_KEY + Constants.PATH_SEPARATOR + id + Constants.MESH_RULE_SUFFIX;
+ }
+
+}
diff --git a/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/controller/MeshRouteControllerTest.java b/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/controller/MeshRouteControllerTest.java
new file mode 100644
index 0000000..9cf6146
--- /dev/null
+++ b/dubbo-admin-server/src/test/java/org/apache/dubbo/admin/controller/MeshRouteControllerTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.AbstractSpringIntegrationTest;
+import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.model.dto.MeshRouteDTO;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.After;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+
+public class MeshRouteControllerTest extends AbstractSpringIntegrationTest {
+
+ private final String env = "whatever";
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @After
+ public void tearDown() throws Exception {
+ if (zkClient.checkExists().forPath("/dubbo") != null) {
+ zkClient.delete().deletingChildrenIfNeeded().forPath("/dubbo");
+ }
+ }
+
+ private String getFileContent(String file) throws IOException {
+ try (InputStream stream = this.getClass().getResourceAsStream(file)) {
+ byte[] bytes = new byte[stream.available()];
+ stream.read(bytes);
+ return new String(bytes, StandardCharsets.UTF_8);
+ }
+ }
+
+
+ @Test
+ public void createMeshRoute() throws IOException {
+ MeshRouteDTO meshRoute = new MeshRouteDTO();
+ ResponseEntity<String> response;
+ String application = "mesh-create";
+ // application are all blank
+ response = restTemplate.postForEntity(url("/api/{env}/rules/route/mesh"), meshRoute, String.class, env);
+ assertFalse("should return a fail response, when application is blank", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+
+ // valid mesh rule
+ meshRoute.setApplication(application);
+ meshRoute.setMeshRule(getFileContent("/MeshRoute.yml"));
+ response = restTemplate.postForEntity(url("/api/{env}/rules/route/mesh"), meshRoute, String.class, env);
+ assertEquals(HttpStatus.CREATED, response.getStatusCode());
+ assertTrue(Boolean.valueOf(response.getBody()));
+ }
+
+
+ @Test
+ public void detailMeshRoute() throws Exception {
+ String id = "1";
+ ResponseEntity<String> response;
+ // when balancing is not exist
+ response = restTemplate.getForEntity(url("/api/{env}/rules/route/mesh/{id}"), String.class, env, id);
+ assertFalse("should return a fail response, when id is null", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+ // when balancing is not null
+ String application = "mesh-detail";
+ String content = getFileContent("/MeshRoute.yml");
+ String path = "/dubbo/" + Constants.CONFIG_KEY + Constants.PATH_SEPARATOR + application + Constants.MESH_RULE_SUFFIX;
+ zkClient.create().creatingParentContainersIfNeeded().forPath(path);
+ zkClient.setData().forPath(path, content.getBytes());
+ assertNotNull("zk path should not be null before deleting", zkClient.checkExists().forPath(path));
+
+ response = restTemplate.getForEntity(url("/api/{env}/rules/route/mesh/{id}"), String.class, env, application);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertEquals(content, objectMapper.readValue(response.getBody(), Map.class).get("meshRule"));
+ }
+
+ @Test
+ public void updateMeshRoute() throws Exception {
+ String application = "mesh-update";
+ String content = getFileContent("/MeshRoute.yml");
+ String path = "/dubbo/" + Constants.CONFIG_KEY + Constants.PATH_SEPARATOR + application + Constants.MESH_RULE_SUFFIX;
+ zkClient.create().creatingParentContainersIfNeeded().forPath(path);
+ zkClient.setData().forPath(path, content.getBytes());
+ assertNotNull("zk path should not be null before deleting", zkClient.checkExists().forPath(path));
+
+ MeshRouteDTO meshRoute = new MeshRouteDTO();
+ meshRoute.setApplication(application);
+ meshRoute.setMeshRule(getFileContent("/MeshRouteTest2.yml"));
+
+ ResponseEntity<String> response = restTemplate.exchange(url("/api/{env}/rules/route/mesh/{id}"), HttpMethod.PUT, new HttpEntity<>(meshRoute, null), String.class, env, application);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertTrue(Boolean.valueOf(response.getBody()));
+ byte[] bytes = zkClient.getData().forPath(path);
+ String updatedConfig = new String(bytes);
+ assertEquals(updatedConfig, meshRoute.getMeshRule());
+ }
+
+
+ @Test
+ public void deleteMeshRoute() throws Exception {
+ String application = "mesh-delete";
+ String content = getFileContent("/MeshRoute.yml");
+ String path = "/dubbo/" + Constants.CONFIG_KEY + Constants.PATH_SEPARATOR + application + Constants.MESH_RULE_SUFFIX;
+ zkClient.create().creatingParentContainersIfNeeded().forPath(path);
+ zkClient.setData().forPath(path, content.getBytes());
+ assertNotNull("zk path should not be null before deleting", zkClient.checkExists().forPath(path));
+
+ ResponseEntity<String> response = restTemplate.exchange(url("/api/{env}/rules/route/mesh/{id}"), HttpMethod.DELETE, new HttpEntity<>(null), String.class, env, application);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertNull(zkClient.checkExists().forPath(path));
+ }
+}
diff --git a/dubbo-admin-server/src/test/resources/MeshRoute.yml b/dubbo-admin-server/src/test/resources/MeshRoute.yml
new file mode 100644
index 0000000..b6a1071
--- /dev/null
+++ b/dubbo-admin-server/src/test/resources/MeshRoute.yml
@@ -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.
+#
+#
+
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: DestinationRule
+metadata: { name: demo-route }
+spec:
+ host: demo
+ subsets:
+ - labels: { env-sign: xxx, tag1: hello }
+ name: isolation
+ - labels: { env-sign: yyy }
+ name: testing-trunk
+ - labels: { env-sign: zzz }
+ name: testing
+ trafficPolicy:
+ loadBalancer: { simple: ROUND_ROBIN }
+
+---
+
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: VirtualService
+metadata: {name: demo-route}
+spec:
+ dubbo:
+ - routedetail:
+ - match:
+ - sourceLabels: {trafficLabel: xxx}
+ name: xxx-project
+ route:
+ - destination: {host: demo, subset: isolation}
+ - match:
+ - sourceLabels: {trafficLabel: testing-trunk}
+ name: testing-trunk
+ route:
+ - destination: {host: demo, subset: testing-trunk}
+ - name: testing
+ route:
+ - destination: {host: demo, subset: testing}
+ services:
+ - {regex: ccc}
+ hosts: [demo]
\ No newline at end of file
diff --git a/dubbo-admin-server/src/test/resources/MeshRouteTest2.yml b/dubbo-admin-server/src/test/resources/MeshRouteTest2.yml
new file mode 100644
index 0000000..4d3454b
--- /dev/null
+++ b/dubbo-admin-server/src/test/resources/MeshRouteTest2.yml
@@ -0,0 +1,41 @@
+#
+#
+# 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.
+#
+#
+
+apiVersion: service.dubbo.apache.org/v1alpha1
+kind: VirtualService
+metadata: {name: demo-route}
+spec:
+ dubbo:
+ - routedetail:
+ - match:
+ - sourceLabels: {trafficLabel: xxx}
+ name: xxx-project
+ route:
+ - destination: {host: demo, subset: isolation}
+ - match:
+ - sourceLabels: {trafficLabel: testing-trunk}
+ name: testing-trunk
+ route:
+ - destination: {host: demo, subset: testing-trunk}
+ - name: testing
+ route:
+ - destination: {host: demo, subset: testing}
+ services:
+ - {regex: ccc}
+ hosts: [demo]
diff --git a/dubbo-admin-ui/src/api/menu.js b/dubbo-admin-ui/src/api/menu.js
index 0a4fced..a68f536 100644
--- a/dubbo-admin-ui/src/api/menu.js
+++ b/dubbo-admin-ui/src/api/menu.js
@@ -23,7 +23,8 @@ const Menu = [
group: 'governance',
items: [
{ title: 'routingRule', path: '/governance/routingRule' },
- { title: 'tagRule', path: '/governance/tagRule', badge: 'new' },
+ { title: 'tagRule', path: '/governance/tagRule' },
+ { title: 'meshRule', path: '/governance/meshRule', badge: 'new' },
{ title: 'accessControl', path: '/governance/access' },
{ title: 'dynamicConfig', path: '/governance/config' },
{ title: 'weightAdjust', path: '/governance/weight' },
diff --git a/dubbo-admin-ui/src/components/governance/MeshRule.vue b/dubbo-admin-ui/src/components/governance/MeshRule.vue
new file mode 100644
index 0000000..f29b5a4
--- /dev/null
+++ b/dubbo-admin-ui/src/components/governance/MeshRule.vue
@@ -0,0 +1,422 @@
+<!--
+ - 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 lg12>
+ <breadcrumb title="meshRule" :items="breads"></breadcrumb>
+ </v-flex>
+ </v-layout>
+ <v-flex lg12>
+ <v-card flat color="transparent">
+ <v-card-text>
+ <v-form>
+ <v-layout row wrap>
+ <v-combobox
+ id="serviceSearch"
+ :loading="searchLoading"
+ :items="typeAhead"
+ :search-input.sync="input"
+ @keyup.enter="submit"
+ v-model="filter"
+ flat
+ append-icon=""
+ hide-no-data
+ :label="$t('searchMeshRule')"
+ ></v-combobox>
+ <v-btn @click="submit" color="primary" large>{{$t('search')}}</v-btn>
+
+ </v-layout>
+ </v-form>
+ </v-card-text>
+ </v-card>
+ </v-flex>
+ <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="meshRoutingRules"
+ hide-actions
+ class="elevation-0"
+ >
+ <template slot="items" slot-scope="props">
+ <td class="text-xs-left">{{ props.item.application }}</td>
+ <td class="text-xs-center px-0">
+ <v-tooltip bottom>
+ <v-icon small
+ class="mr-2"
+ color="blue"
+ slot="activator"
+ @click="itemOperation('visibility', props.item)">visibility
+ </v-icon>
+ <span>{{$t('view')}}</span>
+ </v-tooltip>
+ <v-tooltip bottom>
+ <v-icon small
+ class="mr-2"
+ color="blue"
+ slot="activator"
+ @click="itemOperation('edit', props.item)">edit
+ </v-icon>
+ <span>Edit</span>
+ </v-tooltip>
+ <v-tooltip bottom>
+ <v-icon small
+ class="mr-2"
+ slot="activator"
+ color="red"
+ @click="itemOperation('delete', props.item)">delete
+ </v-icon>
+ <span>Delete</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('createNewMeshRule')}}</span>
+ </v-card-title>
+ <v-card-text>
+ <v-text-field
+ :label="$t('appName')"
+ :hint="$t('appNameHint')"
+ v-model="application"
+ ></v-text-field>
+
+ <v-subheader class="pa-0 mt-3">{{$t('ruleContent')}}</v-subheader>
+ <ace-editor v-model="ruleText" :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)}}</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(warn.status)">{{$t('confirm')}}</v-btn>
+ </v-card-actions>
+ </v-card>
+ </v-dialog>
+
+ </v-container>
+
+</template>
+<script>
+ import yaml from 'js-yaml'
+ import AceEditor from '@/components/public/AceEditor'
+ import operations from '@/api/operation'
+ import Search from '@/components/public/Search'
+ import Breadcrumb from '@/components/public/Breadcrumb'
+
+ export default {
+ components: {
+ AceEditor,
+ Search,
+ Breadcrumb
+ },
+ data: () => ({
+ dropdown_font: ['Service', 'App', 'IP'],
+ ruleKeys: ['enabled', 'force', 'dynamic', 'runtime', 'group', 'version', 'rule'],
+ pattern: 'Service',
+ filter: '',
+ dialog: false,
+ updateId: '',
+ application: '',
+ searchLoading: false,
+ typeAhead: [],
+ input: null,
+ timerID: null,
+ warn: {
+ display: false,
+ title: '',
+ text: '',
+ status: {}
+ },
+ breads: [
+ {
+ text: 'serviceGovernance',
+ href: ''
+ },
+ {
+ text: 'meshRule',
+ href: ''
+ }
+ ],
+ height: 0,
+ operations: operations,
+ meshRoutingRules: [],
+ template: 'apiVersion: service.dubbo.apache.org/v1alpha1\n' +
+ 'kind: DestinationRule\n' +
+ 'metadata: { name: demo-route }\n' +
+ 'spec:\n' +
+ ' host: demo\n' +
+ ' subsets:\n' +
+ ' - labels: { env-sign: xxx, tag1: hello }\n' +
+ ' name: isolation\n' +
+ ' - labels: { env-sign: yyy }\n' +
+ ' name: testing-trunk\n' +
+ ' - labels: { env-sign: zzz }\n' +
+ ' name: testing\n' +
+ ' trafficPolicy:\n' +
+ ' loadBalancer: { simple: ROUND_ROBIN }\n' +
+ '\n' +
+ '---\n' +
+ '\n' +
+ 'apiVersion: service.dubbo.apache.org/v1alpha1\n' +
+ 'kind: VirtualService\n' +
+ 'metadata: {name: demo-route}\n' +
+ 'spec:\n' +
+ ' dubbo:\n' +
+ ' - routedetail:\n' +
+ ' - match:\n' +
+ ' - sourceLabels: {trafficLabel: xxx}\n' +
+ ' name: xxx-project\n' +
+ ' route:\n' +
+ ' - destination: {host: demo, subset: isolation}\n' +
+ ' - match:\n' +
+ ' - sourceLabels: {trafficLabel: testing-trunk}\n' +
+ ' name: testing-trunk\n' +
+ ' route:\n' +
+ ' - destination: {host: demo, subset: testing-trunk}\n' +
+ ' - name: testing\n' +
+ ' route:\n' +
+ ' - destination: {host: demo, subset: testing}\n' +
+ ' services:\n' +
+ ' - {regex: ccc}\n' +
+ ' hosts: [demo]',
+ ruleText: '',
+ readonly: false,
+ headers: []
+ }),
+ methods: {
+ setHeaders: function () {
+ this.headers = [
+ {
+ text: this.$t('appName'),
+ value: 'application',
+ align: 'left'
+ },
+ {
+ text: this.$t('operation'),
+ value: 'operation',
+ sortable: false,
+ width: '115px'
+ }
+ ]
+ },
+ querySelections(v) {
+ if (this.timerID) {
+ clearTimeout(this.timerID)
+ }
+ // Simulated ajax query
+ this.timerID = setTimeout(() => {
+ if (v && v.length >= 4) {
+ this.searchLoading = true
+ this.typeAhead = this.$store.getters.getAppItems(v)
+ this.searchLoading = false
+ this.timerID = null
+ } else {
+ this.typeAhead = []
+ }
+ }, 500)
+ },
+ submit: function () {
+ if (!this.filter) {
+ this.$notify.error('application is needed')
+ return
+ }
+ this.filter = this.filter.trim()
+ this.search(true)
+ },
+ search: function (rewrite) {
+ let url = '/rules/route/mesh/?application' + '=' + this.filter
+ this.$axios.get(url)
+ .then(response => {
+ this.meshRoutingRules = response.data
+ if (rewrite) {
+ this.$router.push({path: 'meshRule', query: {application: this.filter}})
+ }
+ })
+ },
+ closeDialog: function () {
+ this.ruleText = this.template
+ this.updateId = ''
+ this.application = ''
+ 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 () {
+ const rule = {}
+ rule.meshRule = this.ruleText
+ if (!this.application) {
+ this.$notify.error('application is required')
+ return
+ }
+ rule.application = this.application
+ let vm = this
+ if (this.updateId) {
+ if (this.updateId === 'close') {
+ this.closeDialog()
+ } else {
+ rule.id = this.updateId
+ this.$axios.put('/rules/route/mesh/' + rule.id, rule)
+ .then(response => {
+ if (response.status === 200) {
+ vm.search(vm.application, true)
+ vm.closeDialog()
+ vm.$notify.success('Update success')
+ }
+ })
+ }
+ } else {
+ this.$axios.post('/rules/route/mesh/', rule)
+ .then(response => {
+ if (response.status === 201) {
+ vm.search(vm.application, true)
+ vm.filter = vm.application
+ vm.closeDialog()
+ vm.$notify.success('Create success')
+ }
+ })
+ .catch(error => {
+ console.log(error)
+ })
+ }
+ },
+ itemOperation: function (icon, item) {
+ let itemId = item.application
+ switch (icon) {
+ case 'visibility':
+ this.$axios.get('/rules/route/mesh/' + itemId)
+ .then(response => {
+ let meshRoute = response.data
+ this.handleBalance(meshRoute, true)
+ this.updateId = 'close'
+ })
+ break
+ case 'edit':
+ let id = {}
+ id.id = itemId
+ this.$axios.get('/rules/route/mesh/' + itemId)
+ .then(response => {
+ let meshRoute = response.data
+ this.handleBalance(meshRoute, false)
+ this.updateId = itemId
+ })
+ break
+ case 'delete':
+ this.openWarn('warnDeleteMeshRule', 'application: ' + item.application)
+ this.warn.status.operation = 'delete'
+ this.warn.status.id = itemId
+ }
+ },
+ handleBalance: function (meshRoute, readonly) {
+ this.application = meshRoute.application
+ delete meshRoute.id
+ delete meshRoute.application
+ this.ruleText = meshRoute.meshRule
+ this.readonly = readonly
+ this.dialog = true
+ },
+ setHeight: function () {
+ this.height = window.innerHeight * 0.5
+ },
+ deleteItem: function (warnStatus) {
+ let id = warnStatus.id
+ let operation = warnStatus.operation
+ if (operation === 'delete') {
+ this.$axios.delete('/rules/route/mesh/' + id)
+ .then(response => {
+ if (response.status === 200) {
+ this.warn.display = false
+ this.search(this.filter, false)
+ this.$notify.success('Delete success')
+ }
+ })
+ }
+ }
+ },
+ created() {
+ this.setHeight()
+ },
+ computed: {
+ area() {
+ return this.$i18n.locale
+ }
+ },
+ watch: {
+ input(val) {
+ this.querySelections(val)
+ },
+ area() {
+ this.setHeaders()
+ }
+ },
+ mounted: function () {
+ this.setHeaders()
+ this.$store.dispatch('loadAppItems')
+ this.ruleText = this.template
+ let query = this.$route.query
+ let filter = null
+ Object.keys(query).forEach(function (key) {
+ if (key === 'application') {
+ filter = query[key]
+ }
+ })
+ if (filter !== null) {
+ this.filter = filter
+ this.search(false)
+ }
+ }
+
+ }
+</script>
diff --git a/dubbo-admin-ui/src/lang/en.js b/dubbo-admin-ui/src/lang/en.js
index c0d485f..c239380 100644
--- a/dubbo-admin-ui/src/lang/en.js
+++ b/dubbo-admin-ui/src/lang/en.js
@@ -20,6 +20,7 @@ export default {
serviceGovernance: 'Service Governance',
routingRule: 'Condition Rule',
tagRule: 'Tag Rule',
+ meshRule: 'Mesh Rule',
dynamicConfig: 'Dynamic Config',
accessControl: 'Black White List',
weightAdjust: 'Weight Adjust',
@@ -61,6 +62,7 @@ export default {
ruleContent: 'RULE CONTENT',
createNewRoutingRule: 'Create New Routing Rule',
createNewTagRule: 'Create New Tag Rule',
+ createNewMeshRule: 'Create New Mesh Rule',
createNewDynamicConfigRule: 'Create New Dynamic Config Rule',
createNewWeightRule: 'Create New Weight Rule',
createNewLoadBalanceRule: 'Create new load balancing rule',
@@ -86,6 +88,7 @@ export default {
ipSearchHint: 'Find all services provided by the target server on the specified IP address',
appSearchHint: 'Input an application name to find all services provided by one particular application, * for all',
searchTagRule: 'Search Tag Rule by application name',
+ searchMeshRule: 'Search Mesh Rule by application name',
searchSingleMetrics: 'Search Metrics by IP',
searchBalanceRule: 'Search Balancing Rule',
noMetadataHint: 'There is no metadata available, please update to Dubbo2.7, or check your config center configuration in application.properties, please check ',
@@ -137,6 +140,7 @@ export default {
warnDeleteBalancing: 'Are you sure to Delete load balancing',
warnDeleteAccessControl: 'Are you sure to Delete access control',
warnDeleteTagRule: 'Are you sure to Delete tag rule',
+ warnDeleteMeshRule: 'Are you sure to Delete mesh rule',
warnDeleteWeightAdjust: 'Are you sure to Delete weight adjust',
configNameHint: "Application name the config belongs to, use 'global'(without quotes) for global config",
configContent: 'Config Content',
diff --git a/dubbo-admin-ui/src/lang/zh.js b/dubbo-admin-ui/src/lang/zh.js
index 786b494..1116702 100644
--- a/dubbo-admin-ui/src/lang/zh.js
+++ b/dubbo-admin-ui/src/lang/zh.js
@@ -22,6 +22,7 @@ export default {
serviceRelation: '服务关系',
routingRule: '条件路由',
tagRule: '标签路由',
+ meshRule: 'Mesh路由',
dynamicConfig: '动态配置',
accessControl: '黑白名单',
weightAdjust: '权重调整',
@@ -61,6 +62,7 @@ export default {
ruleContent: '规则内容',
createNewRoutingRule: '创建新路由规则',
createNewTagRule: '创建新标签规则',
+ createMeshTagRule: '创建新mesh规则',
createNewDynamicConfigRule: '创建新动态配置规则',
createNewWeightRule: '新建权重规则',
createNewLoadBalanceRule: '新建负载均衡规则',
@@ -86,6 +88,7 @@ export default {
ipSearchHint: '在指定的IP地址上查找目标服务器提供的所有服务',
appSearchHint: '输入应用名称以查找由一个特定应用提供的所有服务, * 代表所有',
searchTagRule: '根据应用名搜索标签规则',
+ searchMeshRule: '根据应用名搜索mesh规则',
searchSingleMetrics: '输入IP搜索Metrics信息',
searchBalanceRule: '搜索负载均衡规则',
parameterList: '参数列表',
@@ -137,6 +140,7 @@ export default {
warnDeleteBalancing: '是否要删除负载均衡规则',
warnDeleteAccessControl: '是否要删除黑白名单',
warnDeleteTagRule: '是否要删除标签路由',
+ warnDeleteMeshRule: '是否要删除mesh路由',
warnDeleteWeightAdjust: '是否要删除权重规则',
configNameHint: '配置所属的应用名, global 表示全局配置',
configContent: '配置内容',
diff --git a/dubbo-admin-ui/src/router/index.js b/dubbo-admin-ui/src/router/index.js
index 1a4c2c1..6343d34 100644
--- a/dubbo-admin-ui/src/router/index.js
+++ b/dubbo-admin-ui/src/router/index.js
@@ -22,6 +22,7 @@ import ServiceDetail from '@/components/ServiceDetail'
import TestMethod from '@/components/test/TestMethod'
import RoutingRule from '@/components/governance/RoutingRule'
import TagRule from '@/components/governance/TagRule'
+import MeshRule from '@/components/governance/MeshRule'
import AccessControl from '@/components/governance/AccessControl'
import LoadBalance from '@/components/governance/LoadBalance'
import WeightAdjust from '@/components/governance/WeightAdjust'
@@ -88,6 +89,14 @@ export default new Router({
}
},
{
+ path: '/governance/meshRule',
+ name: 'MeshRule',
+ component: MeshRule,
+ meta: {
+ requireLogin: true
+ }
+ },
+ {
path: '/governance/access',
name: 'AccessControl',
component: AccessControl,