blob: fe0f085256114af281c588b6656acd5b8efff303 [file] [log] [blame]
/*
* 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.exception.ResourceNotFoundException;
import org.apache.dubbo.admin.common.util.Constants;
import org.apache.dubbo.admin.common.util.ConvertUtil;
import org.apache.dubbo.admin.common.util.RouteUtils;
import org.apache.dubbo.admin.common.util.YamlParser;
import org.apache.dubbo.admin.model.domain.Route;
import org.apache.dubbo.admin.model.dto.AccessDTO;
import org.apache.dubbo.admin.model.dto.ConditionRouteDTO;
import org.apache.dubbo.admin.model.dto.TagRouteDTO;
import org.apache.dubbo.admin.model.store.RoutingRule;
import org.apache.dubbo.admin.model.store.TagRoute;
import org.apache.dubbo.admin.service.RouteService;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
@Component
public class RouteServiceImpl extends AbstractService implements RouteService {
private String prefix = Constants.CONFIG_KEY;
@Override
public void createConditionRoute(ConditionRouteDTO conditionRoute) {
String id = ConvertUtil.getIdFromDTO(conditionRoute);
String path = getPath(id, Constants.CONDITION_ROUTE);
String existConfig = dynamicConfiguration.getConfig(path);
RoutingRule existRule = null;
if (existConfig != null) {
existRule = YamlParser.loadObject(existConfig, RoutingRule.class);
}
existRule = RouteUtils.insertConditionRule(existRule, conditionRoute);
//register2.7
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(existRule));
//register2.6
if (StringUtils.isNotEmpty(conditionRoute.getService())) {
for (Route old : convertRouteToOldRoute(conditionRoute)) {
registry.register(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@Override
public void updateConditionRoute(ConditionRouteDTO newConditionRoute) {
String id = ConvertUtil.getIdFromDTO(newConditionRoute);
String path = getPath(id, Constants.CONDITION_ROUTE);
String existConfig = dynamicConfiguration.getConfig(path);
if (existConfig == null) {
throw new ResourceNotFoundException("no existing condition route for path: " + path);
}
RoutingRule routingRule = YamlParser.loadObject(existConfig, RoutingRule.class);
ConditionRouteDTO oldConditionRoute = RouteUtils.createConditionRouteFromRule(routingRule);
routingRule = RouteUtils.insertConditionRule(routingRule, newConditionRoute);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(routingRule));
//for 2.6
if (StringUtils.isNotEmpty(newConditionRoute.getService())) {
for (Route old : convertRouteToOldRoute(oldConditionRoute)) {
registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
for (Route updated : convertRouteToOldRoute(newConditionRoute)) {
registry.register(updated.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@Override
public void deleteConditionRoute(ConditionRouteDTO conditionRoute) {
String id = ConvertUtil.getIdFromDTO(conditionRoute);
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config == null) {
//throw exception
}
RoutingRule route = YamlParser.loadObject(config, RoutingRule.class);
List<String> blackWhiteList = RouteUtils.filterBlackWhiteListFromConditions(route.getConditions());
if (blackWhiteList.size() != 0) {
route.setConditions(blackWhiteList);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(route));
} else {
dynamicConfiguration.deleteConfig(path);
}
//for 2.6
if (route.getScope().equals(Constants.SERVICE)) {
RoutingRule originRule = YamlParser.loadObject(config, RoutingRule.class);
ConditionRouteDTO conditionRouteDTO = RouteUtils.createConditionRouteFromRule(originRule);
for (Route old : convertRouteToOldRoute(conditionRouteDTO)) {
registry.unregister(old.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@Override
public void deleteAccess(String id) {
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
List<String> blackWhiteList = RouteUtils.filterBlackWhiteListFromConditions(ruleDTO.getConditions());
List<String> conditions = RouteUtils.filterConditionRuleFromConditions(ruleDTO.getConditions());
if (conditions.size() == 0) {
dynamicConfiguration.deleteConfig(path);
} else {
ruleDTO.setConditions(conditions);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
}
//2.6
if (ruleDTO.getScope().equals(Constants.SERVICE) && blackWhiteList.size() > 0) {
Route route = RouteUtils.convertBlackWhiteListtoRoute(blackWhiteList, Constants.SERVICE, id);
registry.unregister(route.toUrl());
}
}
}
@Override
public void createAccess(AccessDTO accessDTO) {
String id = ConvertUtil.getIdFromDTO(accessDTO);
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
List<String> blackWhiteList = RouteUtils.convertToBlackWhiteList(accessDTO);
RoutingRule ruleDTO;
if (config == null) {
ruleDTO = new RoutingRule();
ruleDTO.setEnabled(true);
if (StringUtils.isNoneEmpty(accessDTO.getApplication())) {
ruleDTO.setScope(Constants.APPLICATION);
} else {
ruleDTO.setScope(Constants.SERVICE);
}
ruleDTO.setKey(id);
ruleDTO.setConditions(blackWhiteList);
} else {
ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
if (ruleDTO.getConditions() == null) {
ruleDTO.setConditions(blackWhiteList);
} else {
ruleDTO.getConditions().addAll(blackWhiteList);
}
}
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
//for 2.6
if (ruleDTO.getScope().equals("service")) {
Route route = RouteUtils.convertAccessDTOtoRoute(accessDTO);
registry.register(route.toUrl());
}
}
@Override
public AccessDTO findAccess(String id) {
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
List<String> blackWhiteList = RouteUtils.filterBlackWhiteListFromConditions(ruleDTO.getConditions());
return RouteUtils.convertToAccessDTO(blackWhiteList, ruleDTO.getScope(), ruleDTO.getKey());
}
return null;
}
@Override
public void updateAccess(AccessDTO accessDTO) {
String key = ConvertUtil.getIdFromDTO(accessDTO);
String path = getPath(key, Constants.CONDITION_ROUTE);
List<String> blackWhiteList = RouteUtils.convertToBlackWhiteList(accessDTO);
String config = dynamicConfiguration.getConfig(path);
List<String> oldList = null;
if (config != null) {
RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
oldList = RouteUtils.filterBlackWhiteListFromConditions(ruleDTO.getConditions());
List<String> conditions = RouteUtils.filterConditionRuleFromConditions(ruleDTO.getConditions());
conditions.addAll(blackWhiteList);
ruleDTO.setConditions(conditions);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
}
//2.6
if (StringUtils.isNotEmpty(accessDTO.getService())) {
Route oldRoute = RouteUtils.convertBlackWhiteListtoRoute(oldList, Constants.SERVICE, key);
Route newRoute = RouteUtils.convertAccessDTOtoRoute(accessDTO);
registry.unregister(oldRoute.toUrl());
registry.register(newRoute.toUrl());
}
}
@Override
public void enableConditionRoute(ConditionRouteDTO conditionRoute) {
String id = ConvertUtil.getIdFromDTO(conditionRoute);
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
RoutingRule ruleDTO = YamlParser.loadObject(config, RoutingRule.class);
if (ruleDTO.getScope().equals(Constants.SERVICE)) {
//for2.6
for (Route oldRoute : convertRouteToOldRoute(RouteUtils.createConditionRouteFromRule(ruleDTO))) {
URL oldURL = oldRoute.toUrl();
registry.unregister(oldURL);
oldURL = oldURL.addParameter("enabled", true);
registry.register(oldURL);
}
}
//2.7
ruleDTO.setEnabled(true);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(ruleDTO));
}
}
@Override
public void disableConditionRoute(ConditionRouteDTO conditionRoute) {
String id = ConvertUtil.getIdFromDTO(conditionRoute);
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
RoutingRule routeRule = YamlParser.loadObject(config, RoutingRule.class);
if (routeRule.getScope().equals(Constants.SERVICE)) {
//for 2.6
for (Route oldRoute : convertRouteToOldRoute(RouteUtils.createConditionRouteFromRule(routeRule))) {
URL oldURL = oldRoute.toUrl();
registry.unregister(oldURL);
oldURL = oldURL.addParameter("enabled", false);
registry.register(oldURL);
}
}
//2.7
routeRule.setEnabled(false);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(routeRule));
}
}
@Override
public ConditionRouteDTO findConditionRoute(ConditionRouteDTO crDTO) {
return findConditionRoute(ConvertUtil.getIdFromDTO(crDTO));
}
@Override
public ConditionRouteDTO findConditionRoute(String id) {
String path = getPath(id, Constants.CONDITION_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
RoutingRule routingRule = YamlParser.loadObject(config, RoutingRule.class);
ConditionRouteDTO conditionRouteDTO = RouteUtils.createConditionRouteFromRule(routingRule);
String service = conditionRouteDTO.getService();
if (org.apache.commons.lang3.StringUtils.isNotBlank(service)) {
conditionRouteDTO.setService(service.replace("*", "/"));
}
String[] detachResult = ConvertUtil.detachId(id);
if (detachResult.length > 1) {
conditionRouteDTO.setServiceVersion(detachResult[1]);
conditionRouteDTO.setServiceGroup(detachResult[2]);
}
return conditionRouteDTO;
}
return null;
}
@Override
public void createTagRoute(TagRouteDTO tagRoute) {
String id = ConvertUtil.getIdFromDTO(tagRoute);
String path = getPath(id,Constants.TAG_ROUTE);
TagRoute store = RouteUtils.convertTagroutetoStore(tagRoute);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(store));
}
@Override
public void updateTagRoute(TagRouteDTO tagRoute) {
String id = ConvertUtil.getIdFromDTO(tagRoute);
String path = getPath(id, Constants.TAG_ROUTE);
if (dynamicConfiguration.getConfig(path) == null) {
throw new ResourceNotFoundException("can not find tagroute: " + id);
//throw exception
}
TagRoute store = RouteUtils.convertTagroutetoStore(tagRoute);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(store));
}
@Override
public void deleteTagRoute(String id) {
String path = getPath(id, Constants.TAG_ROUTE);
dynamicConfiguration.deleteConfig(path);
}
@Override
public void enableTagRoute(String id) {
String path = getPath(id, Constants.TAG_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
TagRoute tagRoute = YamlParser.loadObject(config, TagRoute.class);
tagRoute.setEnabled(true);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(tagRoute));
}
}
@Override
public void disableTagRoute(String id) {
String path = getPath(id, Constants.TAG_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
TagRoute tagRoute = YamlParser.loadObject(config, TagRoute.class);
tagRoute.setEnabled(false);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(tagRoute));
}
}
@Override
public TagRouteDTO findTagRoute(String id) {
String path = getPath(id, Constants.TAG_ROUTE);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
TagRoute tagRoute = YamlParser.loadObject(config, TagRoute.class);
return RouteUtils.convertTagroutetoDisplay(tagRoute);
}
return null;
}
private String getPath(String key, String type) {
key = key.replace("/", "*");
if (type.equals(Constants.CONDITION_ROUTE)) {
return prefix + Constants.PATH_SEPARATOR + key + Constants.CONDITION_RULE_SUFFIX;
} else {
return prefix + Constants.PATH_SEPARATOR + key + Constants.TAG_RULE_SUFFIX;
}
}
private String parseCondition(String condition) {
StringBuilder when = new StringBuilder();
StringBuilder then = new StringBuilder();
condition = condition.trim();
if (condition.contains("=>")) {
String[] array = condition.split("=>", 2);
String consumer = array[0].trim();
String provider = array[1].trim();
if (consumer.length() != 0) {
if (when.length() != 0) {
when.append(" & ").append(consumer);
} else {
when.append(consumer);
}
}
if (provider.length() != 0) {
if (then.length() != 0) {
then.append(" & ").append(provider);
} else {
then.append(provider);
}
}
}
return (when.append(" => ").append(then)).toString();
}
private List<Route> convertRouteToOldRoute(ConditionRouteDTO route) {
List<Route> oldList = new LinkedList<Route>();
for (String condition : route.getConditions()) {
Route old = new Route();
old.setService(route.getService());
old.setEnabled(route.isEnabled());
old.setForce(route.isForce());
old.setRuntime(route.isRuntime());
old.setPriority(route.getPriority());
String rule = parseCondition(condition);
old.setRule(rule);
oldList.add(old);
}
return oldList;
}
}