diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java index 330a0a04b..ef2821d92 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java @@ -127,17 +127,21 @@ public class DataSourcePropertiesConfiguration { @JsonIgnore public List getValidField() { - return Arrays.stream(this.getClass().getDeclaredFields()).map(field -> { - try { - if (!ObjectUtils.isEmpty(field.get(this))) { - return field.getName(); - } - } - catch (IllegalAccessException e) { - // won't happen - } - return null; - }).filter(Objects::nonNull).collect(Collectors.toList()); + return Arrays + .stream(this.getClass().getDeclaredFields()) + .filter(field -> !field.isSynthetic()) + .map(field -> { + try { + if (!ObjectUtils.isEmpty(field.get(this))) { + return field.getName(); + } + } catch (IllegalAccessException e) { + // won't happen + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } @JsonIgnore diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/test/java/com/alibaba/cloud/sentinel/datasource/DataSourcePropertiesConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/test/java/com/alibaba/cloud/sentinel/datasource/DataSourcePropertiesConfigurationTests.java new file mode 100644 index 000000000..1dd9dc5ed --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/test/java/com/alibaba/cloud/sentinel/datasource/DataSourcePropertiesConfigurationTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed 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 + * + * https://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 com.alibaba.cloud.sentinel.datasource; + +import com.alibaba.cloud.sentinel.datasource.config.ApolloDataSourceProperties; +import com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author hnyyghk + */ +public class DataSourcePropertiesConfigurationTests { + + @Test + public void testGetValidField() { + DataSourcePropertiesConfiguration configuration = new DataSourcePropertiesConfiguration(); + ApolloDataSourceProperties apollo = new ApolloDataSourceProperties(); + apollo.setNamespaceName("application"); + apollo.setFlowRulesKey("test-flow-rules"); + apollo.setDefaultFlowRuleValue("[]"); + apollo.setDataType("json"); + apollo.setRuleType(RuleType.FLOW); + configuration.setApollo(apollo); + + List validField = configuration.getValidField(); + + assertThat(validField.size()).isEqualTo(1); + assertThat(validField).doesNotContain("$jacocoData"); + assertThat(validField).contains("apollo"); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java index c2b089b62..d965f3848 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java @@ -53,7 +53,7 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { private static final Logger log = LoggerFactory .getLogger(SentinelDataSourceHandler.class); - private List dataTypeList = Arrays.asList("json", "xml"); + private final List dataTypeList = Arrays.asList("json", "xml"); private final String DATA_TYPE_FIELD = "dataType"; @@ -100,11 +100,11 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { }); } - private void registerBean(final AbstractDataSourceProperties dataSourceProperties, - String dataSourceName) { - + protected BeanDefinitionBuilder parseBeanDefinition(final AbstractDataSourceProperties dataSourceProperties, + String dataSourceName) { Map propertyMap = Arrays .stream(dataSourceProperties.getClass().getDeclaredFields()) + .filter(field -> !field.isSynthetic()) .collect(HashMap::new, (m, v) -> { try { v.setAccessible(true); @@ -186,16 +186,22 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { + "-converter"); } } - else if (CONVERTER_CLASS_FIELD.equals(propertyName)) { - return; - } else { - // wired properties - Optional.ofNullable(propertyValue) - .ifPresent(v -> builder.addPropertyValue(propertyName, v)); + if (!CONVERTER_CLASS_FIELD.equals(propertyName)) { + // wired properties + Optional.ofNullable(propertyValue) + .ifPresent(v -> builder.addPropertyValue(propertyName, v)); + } } }); + return builder; + } + + private void registerBean(final AbstractDataSourceProperties dataSourceProperties, + String dataSourceName) { + BeanDefinitionBuilder builder = parseBeanDefinition(dataSourceProperties, dataSourceName); + this.beanFactory.registerBeanDefinition(dataSourceName, builder.getBeanDefinition()); // init in Spring diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandlerTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandlerTests.java new file mode 100644 index 000000000..3b16700ea --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandlerTests.java @@ -0,0 +1,82 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed 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 + * + * https://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 com.alibaba.cloud.sentinel.custom; + +import com.alibaba.cloud.sentinel.SentinelProperties; +import com.alibaba.cloud.sentinel.datasource.RuleType; +import com.alibaba.cloud.sentinel.datasource.config.ApolloDataSourceProperties; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.env.Environment; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Test cases for {@link SentinelDataSourceHandler}. + * + * @author hnyyghk + */ +public class SentinelDataSourceHandlerTests { + + private SentinelDataSourceHandler sentinelDataSourceHandler; + + private DefaultListableBeanFactory beanFactory; + + private SentinelProperties sentinelProperties; + + private Environment env; + + @Before + public void setUp() { + beanFactory = mock(DefaultListableBeanFactory.class); + sentinelProperties = mock(SentinelProperties.class); + env = mock(Environment.class); + sentinelDataSourceHandler = new SentinelDataSourceHandler(beanFactory, sentinelProperties, env); + } + + @Test + public void testParseBeanDefinition() { + ApolloDataSourceProperties dataSourceProperties = new ApolloDataSourceProperties(); + dataSourceProperties.setNamespaceName("application"); + dataSourceProperties.setFlowRulesKey("test-flow-rules"); + dataSourceProperties.setDefaultFlowRuleValue("[]"); + dataSourceProperties.setDataType("json"); + dataSourceProperties.setRuleType(RuleType.FLOW); + String dataSourceName = "ds1" + "-sentinel-" + "apollo" + "-datasource"; + + BeanDefinitionBuilder builder = sentinelDataSourceHandler.parseBeanDefinition(dataSourceProperties, dataSourceName); + MutablePropertyValues propertyValues = builder.getBeanDefinition().getPropertyValues(); + + assertThat(propertyValues.size()).isEqualTo(4); + assertThat(propertyValues).noneMatch(propertyValue -> "$jacocoData".equals(propertyValue.getName())); + assertThat(propertyValues).anyMatch(propertyValue -> "flowRulesKey".equals(propertyValue.getName()) + && dataSourceProperties.getFlowRulesKey().equals(propertyValue.getValue())); + assertThat(propertyValues).anyMatch(propertyValue -> "defaultFlowRuleValue".equals(propertyValue.getName()) + && dataSourceProperties.getDefaultFlowRuleValue().equals(propertyValue.getValue())); + assertThat(propertyValues).anyMatch(propertyValue -> "namespaceName".equals(propertyValue.getName()) + && dataSourceProperties.getNamespaceName().equals(propertyValue.getValue())); + assertThat(propertyValues).anyMatch(propertyValue -> "converter".equals(propertyValue.getName()) + && propertyValue.getValue() instanceof RuntimeBeanReference + && ((RuntimeBeanReference) propertyValue.getValue()).getBeanName().equals("sentinel-" + dataSourceProperties.getDataType() + "-" + dataSourceProperties.getRuleType().getName() + "-converter")); + } + +}