Skip to content

Commit 8a3a2a1

Browse files
authored
[SCB-2843]detect known configuration problems and send warning message (#4138)
1 parent fb4ccaa commit 8a3a2a1

File tree

7 files changed

+236
-2
lines changed

7 files changed

+236
-2
lines changed

core/src/main/java/org/apache/servicecomb/core/SCBEngine.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import org.slf4j.Logger;
6969
import org.slf4j.LoggerFactory;
7070
import org.springframework.context.ApplicationContext;
71+
import org.springframework.core.env.Environment;
7172

7273
import com.google.common.eventbus.AllowConcurrentEvents;
7374
import com.google.common.eventbus.EventBus;
@@ -146,6 +147,14 @@ public void setApplicationContext(ApplicationContext applicationContext) {
146147
this.applicationContext = applicationContext;
147148
}
148149

150+
public Environment getEnvironment() {
151+
if (this.applicationContext == null) {
152+
// some test cases
153+
return null;
154+
}
155+
return this.applicationContext.getEnvironment();
156+
}
157+
149158
public VendorExtensions getVendorExtensions() {
150159
return vendorExtensions;
151160
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.servicecomb.core.bootup;
18+
19+
import org.apache.servicecomb.foundation.common.event.AlarmEvent;
20+
21+
public class ConfigurationProblemsAlarmEvent extends AlarmEvent {
22+
private final String problems;
23+
24+
public ConfigurationProblemsAlarmEvent(Type type, String problems) {
25+
super(type);
26+
this.problems = problems;
27+
}
28+
29+
public String getProblems() {
30+
return problems;
31+
}
32+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.servicecomb.core.bootup;
18+
19+
import java.util.Arrays;
20+
import java.util.Set;
21+
22+
import org.apache.servicecomb.config.ConfigUtil;
23+
import org.apache.servicecomb.core.SCBEngine;
24+
import org.apache.servicecomb.foundation.common.event.AlarmEvent.Type;
25+
import org.apache.servicecomb.foundation.common.event.EventManager;
26+
import org.springframework.core.env.Environment;
27+
28+
/**
29+
* Detect deprecated and wrong usages of configurations
30+
* and print warning messages
31+
* and sending ConfigurationProblemsAlarmEvent.
32+
*/
33+
public class ConfigurationProblemsCollector implements BootUpInformationCollector {
34+
@Override
35+
public String collect(SCBEngine engine) {
36+
if (engine.getEnvironment() == null) {
37+
// some test cases
38+
return null;
39+
}
40+
StringBuilder result = new StringBuilder();
41+
collectCsePrefix(engine.getEnvironment(), result);
42+
collectServiceDefinition(engine.getEnvironment(), result);
43+
collectTimeoutConfiguration(engine.getEnvironment(), result);
44+
if (result.length() <= 0) {
45+
return null;
46+
}
47+
String warnings = "Configurations warnings:\n" + result;
48+
EventManager.post(new ConfigurationProblemsAlarmEvent(Type.OPEN, warnings));
49+
return warnings;
50+
}
51+
52+
private void collectTimeoutConfiguration(Environment environment, StringBuilder result) {
53+
int keepAliveTimeoutInSeconds = environment.getProperty(
54+
"servicecomb.rest.client.connection.keepAliveTimeoutInSeconds", int.class, 60);
55+
int idleTimeoutInSeconds = environment.getProperty(
56+
"servicecomb.rest.client.connection.idleTimeoutInSeconds", int.class, 150);
57+
if (keepAliveTimeoutInSeconds >= idleTimeoutInSeconds) {
58+
result.append("Configuration `servicecomb.rest.client.connection.keepAliveTimeoutInSeconds` is longer than "
59+
+ "servicecomb.rest.client.connection.idleTimeoutInSeconds.");
60+
result.append("[").append(keepAliveTimeoutInSeconds).append(",").append(idleTimeoutInSeconds).append("]\n");
61+
}
62+
keepAliveTimeoutInSeconds = environment.getProperty(
63+
"servicecomb.rest.client.http2.connection.keepAliveTimeoutInSeconds", int.class, 60);
64+
idleTimeoutInSeconds = environment.getProperty(
65+
"servicecomb.rest.client.http2.connection.idleTimeoutInSeconds", int.class, 150);
66+
if (keepAliveTimeoutInSeconds >= idleTimeoutInSeconds) {
67+
result.append("Configuration `servicecomb.rest.client.http2.connection.keepAliveTimeoutInSeconds` is longer than "
68+
+ "servicecomb.rest.client.http2.connection.idleTimeoutInSeconds.");
69+
result.append("[").append(keepAliveTimeoutInSeconds).append(",").append(idleTimeoutInSeconds).append("]\n");
70+
}
71+
}
72+
73+
private void collectServiceDefinition(Environment environment, StringBuilder result) {
74+
if (environment.getProperty("APPLICATION_ID") != null) {
75+
result.append("Configurations `APPLICATION_ID` is deprecated, "
76+
+ "use `servicecomb.service.application` instead.\n");
77+
}
78+
Set<String> names = ConfigUtil.propertiesWithPrefix(environment, "service_description.");
79+
if (!names.isEmpty()) {
80+
result.append("Configurations with prefix `service_description` is deprecated, "
81+
+ "use `servicecomb.service` instead. Find keys ");
82+
result.append(Arrays.toString(names.toArray()));
83+
result.append("\n");
84+
}
85+
}
86+
87+
private void collectCsePrefix(Environment environment, StringBuilder result) {
88+
Set<String> names = ConfigUtil.propertiesWithPrefix(environment, "cse.");
89+
if (!names.isEmpty()) {
90+
result.append("Configurations with prefix `cse` is deprecated, use `servicecomb` instead. Find keys ");
91+
result.append(Arrays.toString(names.toArray()));
92+
result.append("\n");
93+
}
94+
}
95+
96+
@Override
97+
public String collect() {
98+
return null;
99+
}
100+
101+
@Override
102+
public int getOrder() {
103+
return 1000;
104+
}
105+
}

core/src/main/resources/META-INF/services/org.apache.servicecomb.core.bootup.BootUpInformationCollector

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
#
1717

1818
org.apache.servicecomb.core.bootup.ServiceInformationCollector
19-
org.apache.servicecomb.core.bootup.FilterChainCollector
19+
org.apache.servicecomb.core.bootup.FilterChainCollector
20+
org.apache.servicecomb.core.bootup.ConfigurationProblemsCollector

demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/SpringmvcServer.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,29 @@
1717

1818
package org.apache.servicecomb.demo.springmvc;
1919

20+
import org.apache.servicecomb.demo.CategorizedTestCaseRunner;
21+
import org.apache.servicecomb.demo.TestMgr;
2022
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
2123
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
2224

2325
public class SpringmvcServer {
2426
public static void main(String[] args) throws Exception {
2527
Log4jUtils.init();
2628
BeanUtils.init();
29+
30+
runTests();
31+
32+
TestMgr.summary();
33+
if (!TestMgr.isSuccess()) {
34+
System.exit(1);
35+
}
36+
}
37+
38+
private static void runTests() {
39+
try {
40+
CategorizedTestCaseRunner.runCategorizedTestCase("springmvc");
41+
} catch (Exception e) {
42+
TestMgr.failed("runCategorizedTestCase failed", e);
43+
}
2744
}
2845
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.servicecomb.demo.springmvc.server;
18+
19+
import org.apache.servicecomb.core.bootup.ConfigurationProblemsAlarmEvent;
20+
import org.apache.servicecomb.demo.CategorizedTestCase;
21+
import org.apache.servicecomb.demo.TestMgr;
22+
import org.apache.servicecomb.foundation.common.event.EventManager;
23+
import org.springframework.stereotype.Component;
24+
25+
import com.google.common.eventbus.Subscribe;
26+
27+
@Component
28+
public class ConfigurationProblemsCollectorTest implements CategorizedTestCase {
29+
private ConfigurationProblemsAlarmEvent event;
30+
31+
public ConfigurationProblemsCollectorTest() {
32+
EventManager.register(this);
33+
}
34+
35+
@Subscribe
36+
public void onConfigurationProblemsAlarmEvent(ConfigurationProblemsAlarmEvent event) {
37+
this.event = event;
38+
}
39+
40+
@Override
41+
public void testRestTransport() throws Exception {
42+
TestMgr.check(event != null, true);
43+
TestMgr.check(event.getProblems(), "Configurations warnings:\n"
44+
+ "Configurations with prefix `cse` is deprecated, use `servicecomb` instead. Find keys [cse.test.duplicate1]\n"
45+
+ "Configurations `APPLICATION_ID` is deprecated, use `servicecomb.service.application` instead.\n"
46+
+ "Configurations with prefix `service_description` is deprecated, "
47+
+ "use `servicecomb.service` instead. Find keys [service_description.name, service_description.paths, "
48+
+ "service_description.version]\n");
49+
}
50+
}

foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigUtil.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,19 @@
2222
import static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_SERVICECOMB_PREFIX;
2323

2424
import java.util.HashMap;
25+
import java.util.HashSet;
2526
import java.util.Iterator;
2627
import java.util.LinkedHashMap;
2728
import java.util.List;
2829
import java.util.Map;
2930
import java.util.Objects;
31+
import java.util.Set;
3032
import java.util.concurrent.ConcurrentHashMap;
3133
import java.util.concurrent.CopyOnWriteArraySet;
3234
import java.util.stream.Collectors;
3335

3436
import javax.annotation.Nonnull;
3537

36-
import com.google.common.annotations.VisibleForTesting;
3738
import org.apache.commons.configuration.AbstractConfiguration;
3839
import org.apache.commons.configuration.Configuration;
3940
import org.apache.commons.configuration.EnvironmentConfiguration;
@@ -52,7 +53,12 @@
5253
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
5354
import org.slf4j.Logger;
5455
import org.slf4j.LoggerFactory;
56+
import org.springframework.core.env.ConfigurableEnvironment;
57+
import org.springframework.core.env.EnumerablePropertySource;
58+
import org.springframework.core.env.Environment;
59+
import org.springframework.core.env.PropertySource;
5560

61+
import com.google.common.annotations.VisibleForTesting;
5662
import com.netflix.config.ConcurrentCompositeConfiguration;
5763
import com.netflix.config.ConcurrentMapConfiguration;
5864
import com.netflix.config.ConfigurationManager;
@@ -342,4 +348,18 @@ public static CopyOnWriteArraySet<Runnable> getCallbacks(DynamicProperty propert
342348
throw new IllegalStateException(e);
343349
}
344350
}
351+
352+
public static Set<String> propertiesWithPrefix(Environment environment, String prefix) {
353+
Set<String> result = new HashSet<>();
354+
for (PropertySource<?> propertySource : ((ConfigurableEnvironment) environment).getPropertySources()) {
355+
if (propertySource instanceof EnumerablePropertySource) {
356+
for (String key : ((EnumerablePropertySource<?>) propertySource).getPropertyNames()) {
357+
if (key.startsWith(prefix)) {
358+
result.add(key);
359+
}
360+
}
361+
}
362+
}
363+
return result;
364+
}
345365
}

0 commit comments

Comments
 (0)