blob: 1bc018e1e878647aa0c41c66a15284a8d2a04bd0 [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.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.util.Constants;
import org.apache.dubbo.admin.common.util.ConvertUtil;
import org.apache.dubbo.admin.common.util.OverrideUtils;
import org.apache.dubbo.admin.common.util.YamlParser;
import org.apache.dubbo.admin.model.adapter.DynamicConfigDTO2OverrideDTOAdapter;
import org.apache.dubbo.admin.model.adapter.LoadBalance2OverrideAdapter;
import org.apache.dubbo.admin.model.adapter.WeightToOverrideAdapter;
import org.apache.dubbo.admin.model.domain.LoadBalance;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.model.domain.Weight;
import org.apache.dubbo.admin.model.dto.BalancingDTO;
import org.apache.dubbo.admin.model.dto.DynamicConfigDTO;
import org.apache.dubbo.admin.model.dto.WeightDTO;
import org.apache.dubbo.admin.model.store.OverrideConfig;
import org.apache.dubbo.admin.model.store.OverrideDTO;
import org.apache.dubbo.admin.service.OverrideService;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class OverrideServiceImpl extends AbstractService implements OverrideService {
private String prefix = Constants.CONFIG_KEY;
@java.lang.Override
public void saveOverride(DynamicConfigDTO override) {
String id = ConvertUtil.getIdFromDTO(override);
String path = getPath(id);
String exitConfig = dynamicConfiguration.getConfig(path);
List<OverrideConfig> configs = new ArrayList<>();
OverrideDTO existOverride = new DynamicConfigDTO2OverrideDTOAdapter(override);
if (exitConfig != null) {
existOverride = YamlParser.loadObject(exitConfig, OverrideDTO.class);
if (existOverride.getConfigs() != null) {
for (OverrideConfig overrideConfig : existOverride.getConfigs()) {
if (Constants.CONFIGS.contains(overrideConfig.getType())) {
configs.add(overrideConfig);
}
}
}
}
configs.addAll(override.getConfigs());
existOverride.setEnabled(override.isEnabled());
existOverride.setConfigs(configs);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(existOverride));
//for2.6
if (StringUtils.isNotEmpty(override.getService())) {
List<Override> result = convertDTOtoOldOverride(override);
for (Override o : result) {
registry.register(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@java.lang.Override
public void updateOverride(DynamicConfigDTO update) {
String id = ConvertUtil.getIdFromDTO(update);
String path = getPath(id);
String exitConfig = dynamicConfiguration.getConfig(path);
if (exitConfig == null) {
//throw exception
}
OverrideDTO overrideDTO = YamlParser.loadObject(exitConfig, OverrideDTO.class);
DynamicConfigDTO old = OverrideUtils.createFromOverride(overrideDTO);
List<OverrideConfig> configs = new ArrayList<>();
if (overrideDTO.getConfigs() != null) {
List<OverrideConfig> overrideConfigs = overrideDTO.getConfigs();
for (OverrideConfig config : overrideConfigs) {
if (Constants.CONFIGS.contains(config.getType())) {
configs.add(config);
}
}
}
configs.addAll(update.getConfigs());
overrideDTO.setConfigs(configs);
overrideDTO.setEnabled(update.isEnabled());
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
//for 2.6
if (StringUtils.isNotEmpty(update.getService())) {
List<Override> oldOverrides = convertDTOtoOldOverride(old);
List<Override> updatedOverrides = convertDTOtoOldOverride(update);
for (Override o : oldOverrides) {
registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
for (Override o : updatedOverrides) {
registry.register(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@java.lang.Override
public void deleteOverride(String id) {
if (StringUtils.isEmpty(id)) {
// throw exception
}
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
if (config == null) {
//throw exception
}
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
DynamicConfigDTO old = OverrideUtils.createFromOverride(overrideDTO);
List<OverrideConfig> newConfigs = new ArrayList<>();
if (overrideDTO.getConfigs() != null && overrideDTO.getConfigs().size() > 0) {
for (OverrideConfig overrideConfig : overrideDTO.getConfigs()) {
if (Constants.CONFIGS.contains(overrideConfig.getType())) {
newConfigs.add(overrideConfig);
}
}
if (newConfigs.size() == 0) {
dynamicConfiguration.deleteConfig(path);
} else {
overrideDTO.setConfigs(newConfigs);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
}
} else {
dynamicConfiguration.deleteConfig(path);
}
//for 2.6
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
List<Override> overrides = convertDTOtoOldOverride(old);
for (Override o : overrides) {
registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@java.lang.Override
public void enableOverride(String id) {
if (StringUtils.isEmpty(id)) {
//throw exception
}
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
if (config == null) {
//throw exception
}
OverrideDTO override = YamlParser.loadObject(config, OverrideDTO.class);
DynamicConfigDTO old = OverrideUtils.createFromOverride(override);
override.setEnabled(true);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(override));
//2.6
if (Constants.SERVICE.equals(override.getScope())) {
List<Override> overrides = convertDTOtoOldOverride(old);
for (Override o : overrides) {
o.setEnabled(false);
registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
o.setEnabled(true);
registry.register(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@java.lang.Override
public void disableOverride(String id) {
if (StringUtils.isEmpty(id)) {
//throw exception
}
String path = getPath(id);
if (dynamicConfiguration.getConfig(path) == null) {
//throw exception
}
String config = dynamicConfiguration.getConfig(path);
OverrideDTO override = YamlParser.loadObject(config, OverrideDTO.class);
DynamicConfigDTO old = OverrideUtils.createFromOverride(override);
override.setEnabled(false);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(override));
//for 2.6
if (Constants.SERVICE.equals(override.getScope())) {
List<Override> overrides = convertDTOtoOldOverride(old);
for (Override o : overrides) {
o.setEnabled(true);
registry.unregister(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
o.setEnabled(false);
registry.register(o.toUrl().addParameter(Constants.COMPATIBLE_CONFIG, true));
}
}
}
@java.lang.Override
public DynamicConfigDTO findOverride(String id) {
if (StringUtils.isEmpty(id)) {
//throw exception
}
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
DynamicConfigDTO dynamicConfigDTO = OverrideUtils.createFromOverride(overrideDTO);
if (dynamicConfigDTO != null) {
dynamicConfigDTO.setId(id);
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
ConvertUtil.detachIdToService(id, dynamicConfigDTO);
}
}
return dynamicConfigDTO;
}
return null;
}
@java.lang.Override
public void saveWeight(WeightDTO weightDTO) {
String id = ConvertUtil.getIdFromDTO(weightDTO);
String scope = ConvertUtil.getScopeFromDTO(weightDTO);
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
OverrideConfig overrideConfig = OverrideUtils.weightDTOtoConfig(weightDTO);
OverrideDTO overrideDTO = insertConfig(config, overrideConfig, id, scope, Constants.WEIGHT);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
//for 2.6
if (Constants.SERVICE.equals(scope)) {
registerWeight(weightDTO);
}
}
@java.lang.Override
public void updateWeight(WeightDTO weightDTO) {
String id = ConvertUtil.getIdFromDTO(weightDTO);
String scope = ConvertUtil.getScopeFromDTO(weightDTO);
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
WeightDTO oldWeight = null;
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null && configs.size() > 0) {
for (OverrideConfig overrideConfig : configs) {
if (Constants.WEIGHT.equals(overrideConfig.getType())) {
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
oldWeight = OverrideUtils.configtoWeightDTO(overrideConfig, scope, id);
}
int index = configs.indexOf(overrideConfig);
OverrideConfig newConfig = OverrideUtils.weightDTOtoConfig(weightDTO);
configs.set(index, newConfig);
break;
}
}
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
} else {
//throw exception
}
} else {
//throw exception
}
//for 2.6
if (oldWeight != null) {
unregisterWeight(oldWeight);
registerWeight(weightDTO);
}
}
@java.lang.Override
public void deleteWeight(String id) {
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
OverrideConfig oldConfig = null;
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null) {
for (OverrideConfig overrideConfig : configs) {
if (Constants.WEIGHT.equals(overrideConfig.getType())) {
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
oldConfig = overrideConfig;
}
configs.remove(overrideConfig);
break;
}
}
if (configs.size() == 0) {
dynamicConfiguration.deleteConfig(path);
} else {
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
}
}
//for 2.6
if (oldConfig != null) {
String key = overrideDTO.getKey();
WeightDTO weightDTO = OverrideUtils.configtoWeightDTO(oldConfig, overrideDTO.getScope(), key);
unregisterWeight(weightDTO);
}
}
}
@java.lang.Override
public WeightDTO findWeight(String id) {
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null) {
for (OverrideConfig overrideConfig : configs) {
if (Constants.WEIGHT.equals(overrideConfig.getType())) {
WeightDTO weightDTO = OverrideUtils.configtoWeightDTO(overrideConfig, overrideDTO.getScope(), id);
weightDTO.setId(id);
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
ConvertUtil.detachIdToService(id, weightDTO);
}
return weightDTO;
}
}
}
}
return null;
}
@java.lang.Override
public void saveBalance(BalancingDTO balancingDTO) {
String id = ConvertUtil.getIdFromDTO(balancingDTO);
String scope = ConvertUtil.getScopeFromDTO(balancingDTO);
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
OverrideConfig overrideConfig = OverrideUtils.balancingDTOtoConfig(balancingDTO);
OverrideDTO overrideDTO = insertConfig(config, overrideConfig, id, scope, Constants.BALANCING);
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
//for 2.6
if (Constants.SERVICE.equals(scope)) {
registerBalancing(balancingDTO);
}
}
@java.lang.Override
public void updateBalance(BalancingDTO balancingDTO) {
String id = ConvertUtil.getIdFromDTO(balancingDTO);
String scope = ConvertUtil.getScopeFromDTO(balancingDTO);
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
BalancingDTO oldBalancing = null;
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null && configs.size() > 0) {
for (OverrideConfig overrideConfig : configs) {
if (Constants.BALANCING.equals(overrideConfig.getType())) {
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
oldBalancing = OverrideUtils.configtoBalancingDTO(overrideConfig, Constants.SERVICE, overrideDTO.getKey());
}
int index = configs.indexOf(overrideConfig);
OverrideConfig newConfig = OverrideUtils.balancingDTOtoConfig(balancingDTO);
configs.set(index, newConfig);
break;
}
}
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
} else {
//throw exception
}
} else {
//throw exception
}
//for 2.6
if (oldBalancing != null) {
unregisterBalancing(oldBalancing);
registerBalancing(balancingDTO);
}
}
@java.lang.Override
public void deleteBalance(String id) {
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
OverrideConfig oldConfig = null;
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null) {
for (OverrideConfig overrideConfig : configs) {
if (Constants.BALANCING.equals(overrideConfig.getType())) {
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
oldConfig = overrideConfig;
}
configs.remove(overrideConfig);
break;
}
}
if (configs.size() == 0) {
dynamicConfiguration.deleteConfig(path);
} else {
dynamicConfiguration.setConfig(path, YamlParser.dumpObject(overrideDTO));
}
}
//for 2.6
if (oldConfig != null) {
String key = overrideDTO.getKey();
BalancingDTO balancingDTO = OverrideUtils.configtoBalancingDTO(oldConfig, Constants.SERVICE, key);
unregisterBalancing(balancingDTO);
}
}
}
@java.lang.Override
public BalancingDTO findBalance(String id) {
String path = getPath(id);
String config = dynamicConfiguration.getConfig(path);
if (config != null) {
OverrideDTO overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null) {
for (OverrideConfig overrideConfig : configs) {
if (Constants.BALANCING.equals(overrideConfig.getType())) {
BalancingDTO balancingDTO = OverrideUtils.configtoBalancingDTO(overrideConfig, overrideDTO.getScope(), id);
balancingDTO.setId(id);
if (Constants.SERVICE.equals(overrideDTO.getScope())) {
ConvertUtil.detachIdToService(id, balancingDTO);
}
return balancingDTO;
}
}
}
}
return null;
}
private OverrideDTO insertConfig(String config, OverrideConfig overrideConfig, String key, String scope, String configType) {
OverrideDTO overrideDTO = null;
if(config == null) {
overrideDTO = new OverrideDTO();
overrideDTO.setKey(key);
overrideDTO.setScope(scope);
List<OverrideConfig> configs = new ArrayList<>();
configs.add(overrideConfig);
overrideDTO.setConfigs(configs);
} else {
overrideDTO = YamlParser.loadObject(config, OverrideDTO.class);
List<OverrideConfig> configs = overrideDTO.getConfigs();
if (configs != null) {
for (OverrideConfig o : configs) {
if (configType.equals(o.getType())) {
configs.remove(o);
break;
}
}
configs.add(overrideConfig);
} else {
configs = new ArrayList<>();
configs.add(overrideConfig);
}
overrideDTO.setConfigs(configs);
}
return overrideDTO;
}
private void overrideDTOToParams(Override override, OverrideConfig config) {
Map<String, Object> parameters = config.getParameters();
StringBuilder params = new StringBuilder();
if (parameters != null) {
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
String value = entry.getKey() + "=" + entry.getValue();
params.append(value).append("&");
}
}
if (StringUtils.isNotEmpty(params)) {
int length = params.length();
if (params.charAt(length - 1) == '&') {
params.deleteCharAt(length - 1);
}
}
override.setParams(params.toString());
}
private List<Override> convertDTOtoOldOverride(DynamicConfigDTO overrideDTO) {
List<Override> result = new ArrayList<>();
List<OverrideConfig> configs = overrideDTO.getConfigs();
for (OverrideConfig config : configs) {
if (Constants.CONFIGS.contains(config.getType())) {
continue;
}
List<String> apps = config.getApplications();
List<String> addresses = config.getAddresses();
for (String address : addresses) {
if (apps != null && apps.size() > 0) {
for (String app : apps) {
Override override = new Override();
override.setService(overrideDTO.getService());
override.setAddress(address);
override.setEnabled(overrideDTO.isEnabled());
overrideDTOToParams(override, config);
override.setApplication(app);
result.add(override);
}
} else {
Override override = new Override();
override.setService(overrideDTO.getService());
override.setAddress(address);
override.setEnabled(overrideDTO.isEnabled());
overrideDTOToParams(override, config);
result.add(override);
}
}
}
return result;
}
private String getPath(String key) {
key = key.replace("/", "*");
return prefix + Constants.PATH_SEPARATOR + key + Constants.CONFIGURATOR_RULE_SUFFIX;
}
private void unregisterWeight(WeightDTO weightDTO) {
List<String> addresses = weightDTO.getAddresses();
if (addresses != null) {
Weight weight = new Weight();
weight.setService(weightDTO.getService());
weight.setWeight(weightDTO.getWeight());
for (String address : addresses) {
weight.setAddress(address);
Override override = new WeightToOverrideAdapter(weight);
registry.unregister(override.toUrl());
}
}
}
private void registerWeight(WeightDTO weightDTO) {
List<String> addresses = weightDTO.getAddresses();
if (addresses != null) {
Weight weight = new Weight();
weight.setService(weightDTO.getService());
weight.setWeight(weightDTO.getWeight());
for (String address : addresses) {
weight.setAddress(address);
Override override = new WeightToOverrideAdapter(weight);
registry.register(override.toUrl());
}
}
}
private void unregisterBalancing(BalancingDTO balancingDTO) {
LoadBalance loadBalance = new LoadBalance();
loadBalance.setService(balancingDTO.getService());
loadBalance.setMethod(balancingDTO.getMethodName());
loadBalance.setStrategy(balancingDTO.getStrategy());
registry.unregister(new LoadBalance2OverrideAdapter(loadBalance).toUrl());
}
private void registerBalancing(BalancingDTO balancingDTO) {
LoadBalance loadBalance = new LoadBalance();
loadBalance.setService(balancingDTO.getService());
loadBalance.setMethod(balancingDTO.getMethodName());
loadBalance.setStrategy(balancingDTO.getStrategy());
registry.register(new LoadBalance2OverrideAdapter(loadBalance).toUrl());
}
}