Commit aabd5047 by Nepxion

增加细粒度版本控制

parent 5301a0eb
......@@ -9,6 +9,7 @@ package com.nepxion.discovery.plugin.configuration;
* @version 1.0
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
......@@ -23,11 +24,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import com.nepxion.discovery.plugin.configuration.constant.ConfigurationConstant;
import com.nepxion.discovery.plugin.configuration.xml.Dom4JParser;
import com.nepxion.discovery.plugin.core.entity.ConsumerEntity;
import com.nepxion.discovery.plugin.core.entity.DiscoveryEntity;
import com.nepxion.discovery.plugin.core.entity.DiscoveryServiceEntity;
import com.nepxion.discovery.plugin.core.entity.PluginEntity;
import com.nepxion.discovery.plugin.core.entity.RegisterEntity;
import com.nepxion.discovery.plugin.core.entity.FilterType;
import com.nepxion.discovery.plugin.core.entity.DiscoveryEntity;
import com.nepxion.discovery.plugin.core.entity.RegisterFilterType;
import com.nepxion.discovery.plugin.core.exception.PluginException;
public class ConfigurationParser extends Dom4JParser {
......@@ -88,7 +89,7 @@ public class ConfigurationParser extends Dom4JParser {
throw new PluginException("Attribute[" + ConfigurationConstant.FILTER_TYPE_ATTRIBUTE_NAME + "] in element[" + element.getName() + "] is missing");
}
String filterType = filterTypeAttribute.getData().toString().trim();
registerEntity.setFilterType(FilterType.fromString(filterType));
registerEntity.setFilterType(RegisterFilterType.fromString(filterType));
Attribute globalFilterAttribute = element.attribute(ConfigurationConstant.FILTER_VALUE_ATTRIBUTE_NAME);
if (globalFilterAttribute != null) {
......@@ -121,48 +122,47 @@ public class ConfigurationParser extends Dom4JParser {
@SuppressWarnings("rawtypes")
private void parseDiscovery(Element element, DiscoveryEntity discoveryEntity) {
List<ConsumerEntity> consumerEntityList = discoveryEntity.getConsumerEntityList();
Map<String, List<DiscoveryServiceEntity>> serviceEntityMap = discoveryEntity.getServiceEntityMap();
for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
Object childElementObject = elementIterator.next();
if (childElementObject instanceof Element) {
Element childElement = (Element) childElementObject;
ConsumerEntity consumerEntity = new ConsumerEntity();
Attribute serviceNameAttribute = childElement.attribute(ConfigurationConstant.SERVICE_NAME_ATTRIBUTE_NAME);
if (serviceNameAttribute == null) {
throw new PluginException("Attribute[" + ConfigurationConstant.SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
}
String serviceName = serviceNameAttribute.getData().toString().trim();
consumerEntity.setServiceName(serviceName);
parseConsumer(childElement, consumerEntity);
DiscoveryServiceEntity serviceEntity = new DiscoveryServiceEntity();
consumerEntityList.add(consumerEntity);
}
Attribute consumerServiceNameAttribute = childElement.attribute(ConfigurationConstant.CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME);
if (consumerServiceNameAttribute == null) {
throw new PluginException("Attribute[" + ConfigurationConstant.CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
}
String consumerServiceName = consumerServiceNameAttribute.getData().toString().trim();
serviceEntity.setConsumerServiceName(consumerServiceName);
Attribute providerServiceNameAttribute = childElement.attribute(ConfigurationConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME);
if (providerServiceNameAttribute == null) {
throw new PluginException("Attribute[" + ConfigurationConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
}
String providerServiceName = providerServiceNameAttribute.getData().toString().trim();
serviceEntity.setProviderServiceName(providerServiceName);
@SuppressWarnings("rawtypes")
private void parseConsumer(Element element, ConsumerEntity consumerEntity) {
Map<String, String> providerMap = consumerEntity.getProviderMap();
for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
Object childElementObject = elementIterator.next();
if (childElementObject instanceof Element) {
Element childElement = (Element) childElementObject;
Attribute consumerVersionValueAttribute = childElement.attribute(ConfigurationConstant.CONSUMER_VERSION_VALUE_ATTRIBUTE_NAME);
if (consumerVersionValueAttribute != null) {
String consumerVersionValue = consumerVersionValueAttribute.getData().toString().trim();
serviceEntity.setConsumerVersionValue(consumerVersionValue);
}
Attribute serviceNameAttribute = childElement.attribute(ConfigurationConstant.SERVICE_NAME_ATTRIBUTE_NAME);
if (serviceNameAttribute == null) {
throw new PluginException("Attribute[" + ConfigurationConstant.SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
Attribute providerVersionValueAttribute = childElement.attribute(ConfigurationConstant.PROVIDER_VERSION_VALUE_ATTRIBUTE_NAME);
if (providerVersionValueAttribute != null) {
String providerVersionValue = providerVersionValueAttribute.getData().toString().trim();
serviceEntity.setProviderVersionValue(providerVersionValue);
}
String serviceName = serviceNameAttribute.getData().toString().trim();
Attribute versionValueAttribute = childElement.attribute(ConfigurationConstant.VERSION_VALUE_NAME_ATTRIBUTE_NAME);
if (versionValueAttribute == null) {
throw new PluginException("Attribute[" + ConfigurationConstant.VERSION_VALUE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
List<DiscoveryServiceEntity> serviceEntityList = serviceEntityMap.get(consumerServiceName);
if (serviceEntityList == null) {
serviceEntityList = new ArrayList<DiscoveryServiceEntity>();
serviceEntityMap.put(consumerServiceName, serviceEntityList);
}
String versionValue = versionValueAttribute.getData().toString().trim();
providerMap.put(serviceName, versionValue);
serviceEntityList.add(serviceEntity);
}
}
}
......
......@@ -19,7 +19,8 @@ public class ConfigurationConstant {
public static final String FILTER_VALUE_ATTRIBUTE_NAME = "filter-value";
public static final String SERVICE_NAME_ATTRIBUTE_NAME = "service-name";
public static final String DISCOVERY_ELEMENT_NAME = "discovery";
public static final String CONSUMER_ELEMENT_NAME = "consumer";
public static final String PROVIDER_ELEMENT_NAME = "provider";
public static final String VERSION_VALUE_NAME_ATTRIBUTE_NAME = "version-value";
public static final String CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME = "consumer-service-name";
public static final String PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME = "provider-service-name";
public static final String CONSUMER_VERSION_VALUE_ATTRIBUTE_NAME = "consumer-version-value";
public static final String PROVIDER_VERSION_VALUE_ATTRIBUTE_NAME = "provider-version-value";
}
\ No newline at end of file
......@@ -13,7 +13,8 @@ public class PluginConstant {
public static final String SPRING_APPLICATION_DISCOVERY_VERSION_ENABLED = "spring.application.discovery.version.enabled";
public static final String SPRING_APPLICATION_NAME = "spring.application.name";
public static final String EUREKA_METADATA_VERSION = "version";
public static final String EUREKA_METADATA_VERSION = "eureka.instance.metadataMap.version";
public static final String VRESION = "version";
public static final String SEPARATE = ";";
}
\ No newline at end of file
......@@ -48,9 +48,10 @@ public class DiscoveryClientDecorator implements DiscoveryClient {
boolean discoveryVersionEnabled = Boolean.valueOf(environment.getProperty(PluginConstant.SPRING_APPLICATION_DISCOVERY_VERSION_ENABLED));
if (discoveryVersionEnabled) {
String applicationName = environment.getProperty(PluginConstant.SPRING_APPLICATION_NAME);
String metadataVersion = environment.getProperty(PluginConstant.EUREKA_METADATA_VERSION);
DiscoveryStrategy discoveryStrategy = applicationContext.getBean(DiscoveryStrategy.class);
discoveryStrategy.apply(applicationName, serviceId, instances);
discoveryStrategy.apply(applicationName, metadataVersion, serviceId, instances);
}
return instances;
......
......@@ -10,8 +10,9 @@ package com.nepxion.discovery.plugin.core.entity;
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
......@@ -21,18 +22,18 @@ import org.apache.commons.lang3.builder.ToStringStyle;
public class DiscoveryEntity implements Serializable {
private static final long serialVersionUID = 6281838121286637807L;
private List<ConsumerEntity> consumerEntityList = new ArrayList<ConsumerEntity>();
private Map<String, List<DiscoveryServiceEntity>> serviceEntityMap = new LinkedHashMap<String, List<DiscoveryServiceEntity>>();
public DiscoveryEntity() {
}
public List<ConsumerEntity> getConsumerEntityList() {
return consumerEntityList;
public Map<String, List<DiscoveryServiceEntity>> getServiceEntityMap() {
return serviceEntityMap;
}
public void setConsumerEntityList(List<ConsumerEntity> consumerEntityList) {
this.consumerEntityList = consumerEntityList;
public void setServiceEntityMap(Map<String, List<DiscoveryServiceEntity>> serviceEntityMap) {
this.serviceEntityMap = serviceEntityMap;
}
@Override
......
......@@ -10,38 +10,54 @@ package com.nepxion.discovery.plugin.core.entity;
*/
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class ConsumerEntity implements Serializable {
public class DiscoveryServiceEntity implements Serializable {
private static final long serialVersionUID = -2976565258172148792L;
private String serviceName;
private Map<String, String> providerMap = new LinkedHashMap<String, String>();
private String consumerServiceName;
private String providerServiceName;
private String consumerVersionValue;
private String providerVersionValue;
public ConsumerEntity() {
public DiscoveryServiceEntity() {
}
public String getServiceName() {
return serviceName;
public String getConsumerServiceName() {
return consumerServiceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
public void setConsumerServiceName(String consumerServiceName) {
this.consumerServiceName = consumerServiceName;
}
public Map<String, String> getProviderMap() {
return providerMap;
public String getProviderServiceName() {
return providerServiceName;
}
public void setProviderMap(Map<String, String> providerMap) {
this.providerMap = providerMap;
public void setProviderServiceName(String providerServiceName) {
this.providerServiceName = providerServiceName;
}
public String getConsumerVersionValue() {
return consumerVersionValue;
}
public void setConsumerVersionValue(String consumerVersionValue) {
this.consumerVersionValue = consumerVersionValue;
}
public String getProviderVersionValue() {
return providerVersionValue;
}
public void setProviderVersionValue(String providerVersionValue) {
this.providerVersionValue = providerVersionValue;
}
@Override
......
......@@ -21,7 +21,7 @@ import org.apache.commons.lang3.builder.ToStringStyle;
public class RegisterEntity implements Serializable {
private static final long serialVersionUID = -2097322826969006191L;
private FilterType filterType;
private RegisterFilterType filterType;
private String filterValue;
private Map<String, String> filterMap = new LinkedHashMap<String, String>();
......@@ -29,11 +29,11 @@ public class RegisterEntity implements Serializable {
}
public FilterType getFilterType() {
public RegisterFilterType getFilterType() {
return filterType;
}
public void setFilterType(FilterType filterType) {
public void setFilterType(RegisterFilterType filterType) {
this.filterType = filterType;
}
......
......@@ -9,14 +9,14 @@ package com.nepxion.discovery.plugin.core.entity;
* @version 1.0
*/
public enum FilterType {
public enum RegisterFilterType {
BLACKLIST("BLACKLIST", "黑名单"),
WHITELIST("WHITELIST", "白名单");
private String value;
private String description;
private FilterType(String value, String description) {
private RegisterFilterType(String value, String description) {
this.value = value;
this.description = description;
}
......@@ -29,8 +29,8 @@ public enum FilterType {
return description;
}
public static FilterType fromString(String value) {
for (FilterType type : FilterType.values()) {
public static RegisterFilterType fromString(String value) {
for (RegisterFilterType type : RegisterFilterType.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
return type;
}
......
......@@ -9,62 +9,100 @@ package com.nepxion.discovery.plugin.core.strategy;
* @version 1.0
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import com.nepxion.discovery.plugin.core.cache.PluginCache;
import com.nepxion.discovery.plugin.core.constant.PluginConstant;
import com.nepxion.discovery.plugin.core.entity.ConsumerEntity;
import com.nepxion.discovery.plugin.core.entity.PluginEntity;
import com.nepxion.discovery.plugin.core.entity.DiscoveryEntity;
import com.nepxion.discovery.plugin.core.entity.DiscoveryServiceEntity;
import com.nepxion.discovery.plugin.core.entity.PluginEntity;
public class DiscoveryStrategy {
@Autowired
private PluginEntity pluginEntity;
@Autowired
private PluginCache pluginCache;
@Autowired
private ReentrantReadWriteLock reentrantReadWriteLock;
public void apply(String consumerServiceId, String providerServiceId, List<ServiceInstance> instances) {
public void apply(String consumerServiceId, String consumerServiceVersion, String providerServiceId, List<ServiceInstance> instances) {
try {
reentrantReadWriteLock.readLock().lock();
applyVersionFilter(consumerServiceId, consumerServiceVersion, providerServiceId, instances);
} finally {
reentrantReadWriteLock.readLock().unlock();
}
}
private void applyVersionFilter(String consumerServiceId, String consumerServiceVersion, String providerServiceId, List<ServiceInstance> instances) {
DiscoveryEntity discoveryEntity = pluginEntity.getDiscoveryEntity();
ConsumerEntity consumerEntity = getConsumerEntity(consumerServiceId, discoveryEntity);
if (consumerEntity != null) {
Map<String, String> providerMap = consumerEntity.getProviderMap();
String version = providerMap.get(providerServiceId);
String[] versionArray = StringUtils.split(version, PluginConstant.SEPARATE);
List<String> versionList = Arrays.asList(versionArray);
Iterator<ServiceInstance> iterator = instances.iterator();
while (iterator.hasNext()) {
ServiceInstance serviceInstance = iterator.next();
String metaDataVersion = serviceInstance.getMetadata().get(PluginConstant.EUREKA_METADATA_VERSION);
if (!versionList.contains(metaDataVersion)) {
iterator.remove();
Map<String, List<DiscoveryServiceEntity>> serviceEntityMap = discoveryEntity.getServiceEntityMap();
// 未找到相应的版本定义或者未定义
if (MapUtils.isEmpty(serviceEntityMap)) {
return;
}
List<DiscoveryServiceEntity> serviceEntityList = serviceEntityMap.get(consumerServiceId);
// 未找到相应的版本定义或者未定义
if (CollectionUtils.isEmpty(serviceEntityList)) {
return;
}
// 当前版本的消费者所能调用提供者的版本列表
List<String> allFilterVersions = new ArrayList<String>();
for (DiscoveryServiceEntity serviceEntity : serviceEntityList) {
String providerServiceName = serviceEntity.getProviderServiceName();
if (StringUtils.equals(providerServiceName, providerServiceId)) {
String consumerVersionValue = serviceEntity.getConsumerVersionValue();
String providerVersionValue = serviceEntity.getProviderVersionValue();
List<String> consumerVersionList = getVersionList(consumerVersionValue);
List<String> providerVersionList = getVersionList(providerVersionValue);
// 判断consumer-version-value值是否包含当前消费者的版本号
if (CollectionUtils.isNotEmpty(consumerVersionList) && consumerVersionList.contains(consumerServiceVersion)) {
if (CollectionUtils.isNotEmpty(providerVersionList)) {
allFilterVersions.addAll(providerVersionList);
}
}
} finally {
reentrantReadWriteLock.readLock().unlock();
}
}
private ConsumerEntity getConsumerEntity(String consumerServiceId, DiscoveryEntity discoveryEntity) {
List<ConsumerEntity> consumerEntityList = discoveryEntity.getConsumerEntityList();
for (ConsumerEntity consumerEntity : consumerEntityList) {
String serviceName = consumerEntity.getServiceName();
if (StringUtils.equals(consumerServiceId, serviceName)) {
return consumerEntity;
// 未找到相应的版本定义或者未定义
if (CollectionUtils.isEmpty(allFilterVersions)) {
return;
}
Iterator<ServiceInstance> iterator = instances.iterator();
while (iterator.hasNext()) {
ServiceInstance serviceInstance = iterator.next();
String metaDataVersion = serviceInstance.getMetadata().get(PluginConstant.VRESION);
if (!allFilterVersions.contains(metaDataVersion)) {
iterator.remove();
}
}
}
private List<String> getVersionList(String versionValue) {
if (StringUtils.isEmpty(versionValue)) {
return null;
}
String[] versionArray = StringUtils.split(versionValue, PluginConstant.SEPARATE);
return Arrays.asList(versionArray);
}
}
\ No newline at end of file
......@@ -18,9 +18,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.nepxion.discovery.plugin.core.constant.PluginConstant;
import com.nepxion.discovery.plugin.core.entity.RegisterFilterType;
import com.nepxion.discovery.plugin.core.entity.PluginEntity;
import com.nepxion.discovery.plugin.core.entity.RegisterEntity;
import com.nepxion.discovery.plugin.core.entity.FilterType;
import com.nepxion.discovery.plugin.core.exception.PluginException;
public class RegisterStrategy {
......@@ -36,8 +36,15 @@ public class RegisterStrategy {
try {
reentrantReadWriteLock.readLock().lock();
applyIpAddressFilter(serviceId, ipAddress);
} finally {
reentrantReadWriteLock.readLock().unlock();
}
}
private void applyIpAddressFilter(String serviceId, String ipAddress) {
RegisterEntity registerEntity = pluginEntity.getRegisterEntity();
FilterType filterType = registerEntity.getFilterType();
RegisterFilterType filterType = registerEntity.getFilterType();
String globalFilterValue = registerEntity.getFilterValue();
......@@ -61,10 +68,6 @@ public class RegisterStrategy {
validateWhitelist(allFilterValue, ipAddress);
break;
}
} finally {
reentrantReadWriteLock.readLock().unlock();
}
}
private void validateBlacklist(String filterValue, String ipAddress) {
......
......@@ -37,7 +37,7 @@ public class DiscoveryConfigurationSimulator {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// 本地文件模拟代替远程文件,随机读取
int index = threadLocalRandom.nextInt(4) + 1;
int index = threadLocalRandom.nextInt(5) + 1;
InputStream inputStream = getInputStream("src/main/resources/plugin" + index + ".xml");
configurationPublisher.publish(inputStream);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment