/configuration/src/test/java/com/proofpoint/configuration/ConfigurationFactoryTest.java

https://github.com/ssindkar/platform · Java · 1126 lines · 1009 code · 100 blank · 17 comment · 0 complexity · b38018498e97081e62c112891d1f1cce MD5 · raw file

  1. /*
  2. * Copyright 2010 Proofpoint, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.proofpoint.configuration;
  17. import com.google.common.collect.ImmutableList;
  18. import com.google.common.collect.ImmutableMap;
  19. import com.google.inject.Binder;
  20. import com.google.inject.CreationException;
  21. import com.google.inject.Guice;
  22. import com.google.inject.Injector;
  23. import com.google.inject.Module;
  24. import com.google.inject.spi.Message;
  25. import org.testng.annotations.Test;
  26. import javax.validation.constraints.Max;
  27. import javax.validation.constraints.Min;
  28. import javax.validation.constraints.NotNull;
  29. import java.util.Collections;
  30. import java.util.HashMap;
  31. import java.util.List;
  32. import java.util.Map;
  33. import java.util.TreeMap;
  34. import static com.google.common.base.MoreObjects.firstNonNull;
  35. import static com.proofpoint.configuration.ConfigBinder.bindConfig;
  36. import static com.proofpoint.testing.Assertions.assertContainsAllOf;
  37. import static org.testng.Assert.assertEquals;
  38. import static org.testng.Assert.assertNotNull;
  39. import static org.testng.Assert.fail;
  40. @SuppressWarnings("deprecation")
  41. public class ConfigurationFactoryTest
  42. {
  43. private static final ConfigurationDefaultingModule TEST_DEFAULTING_MODULE = new ConfigurationDefaultingModule()
  44. {
  45. @Override
  46. public Map<String, String> getConfigurationDefaults()
  47. {
  48. throw new UnsupportedOperationException();
  49. }
  50. @Override
  51. public void configure(Binder binder)
  52. {
  53. throw new UnsupportedOperationException();
  54. }
  55. @Override
  56. public String toString()
  57. {
  58. return "testing module";
  59. }
  60. };
  61. @Test
  62. public void testAnnotatedGettersThrows()
  63. {
  64. Map<String, String> properties = new TreeMap<>();
  65. properties.put("string-value", "some value");
  66. properties.put("boolean-value", "true");
  67. TestMonitor monitor = new TestMonitor();
  68. try {
  69. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(AnnotatedGetter.class));
  70. fail("Expected an exception in object creation due to conflicting configuration");
  71. }
  72. catch (CreationException e) {
  73. monitor.assertNumberOfErrors(2);
  74. assertContainsAllOf(e.getMessage(), "not a valid setter", "getStringValue");
  75. assertContainsAllOf(e.getMessage(), "not a valid setter", "isBooleanValue");
  76. }
  77. }
  78. @Test
  79. public void testAnnotatedSetters()
  80. {
  81. Map<String, String> properties = new TreeMap<>();
  82. properties.put("string-value", "some value");
  83. properties.put("boolean-value", "true");
  84. TestMonitor monitor = new TestMonitor();
  85. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  86. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  87. monitor.assertNumberOfErrors(0);
  88. monitor.assertNumberOfWarnings(0);
  89. assertNotNull(annotatedSetter);
  90. assertEquals(annotatedSetter.getStringValue(), "some value");
  91. assertEquals(annotatedSetter.isBooleanValue(), true);
  92. }
  93. @Test
  94. public void testModuleDefaults()
  95. {
  96. Map<String, String> moduleDefaults = ImmutableMap.of(
  97. "string-value", "some value",
  98. "boolean-value", "true"
  99. );
  100. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  101. "string-value", TEST_DEFAULTING_MODULE,
  102. "boolean-value", TEST_DEFAULTING_MODULE
  103. );
  104. TestMonitor monitor = new TestMonitor();
  105. Injector injector = createInjector(ImmutableMap.of(), null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  106. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  107. monitor.assertNumberOfErrors(0);
  108. monitor.assertNumberOfWarnings(0);
  109. assertNotNull(annotatedSetter);
  110. assertEquals(annotatedSetter.getStringValue(), "some value");
  111. assertEquals(annotatedSetter.isBooleanValue(), true);
  112. }
  113. @Test
  114. public void testApplicationDefaults()
  115. {
  116. Map<String, String> applicationDefaults = ImmutableMap.of(
  117. "string-value", "some value",
  118. "boolean-value", "true"
  119. );
  120. TestMonitor monitor = new TestMonitor();
  121. Injector injector = createInjector(ImmutableMap.of(), applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  122. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  123. monitor.assertNumberOfErrors(0);
  124. monitor.assertNumberOfWarnings(0);
  125. assertNotNull(annotatedSetter);
  126. assertEquals(annotatedSetter.getStringValue(), "some value");
  127. assertEquals(annotatedSetter.isBooleanValue(), true);
  128. }
  129. @Test
  130. public void testPropertiesOverrideModuleDefaults()
  131. {
  132. Map<String, String> properties = ImmutableMap.of(
  133. "string-value", "some value",
  134. "boolean-value", "false"
  135. );
  136. Map<String, String> moduleDefaults = ImmutableMap.of(
  137. "string-value", "some default value",
  138. "boolean-value", "true"
  139. );
  140. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  141. "string-value", TEST_DEFAULTING_MODULE,
  142. "boolean-value", TEST_DEFAULTING_MODULE
  143. );
  144. TestMonitor monitor = new TestMonitor();
  145. Injector injector = createInjector(properties, null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  146. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  147. monitor.assertNumberOfErrors(0);
  148. monitor.assertNumberOfWarnings(0);
  149. assertNotNull(annotatedSetter);
  150. assertEquals(annotatedSetter.getStringValue(), "some value");
  151. assertEquals(annotatedSetter.isBooleanValue(), false);
  152. }
  153. @Test
  154. public void testApplicationDefaultsOverrideModuleDefaults()
  155. {
  156. Map<String, String> applicationDefaults = ImmutableMap.of(
  157. "string-value", "some value",
  158. "boolean-value", "false"
  159. );
  160. Map<String, String> moduleDefaults = ImmutableMap.of(
  161. "string-value", "some default value",
  162. "boolean-value", "true"
  163. );
  164. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  165. "string-value", TEST_DEFAULTING_MODULE,
  166. "boolean-value", TEST_DEFAULTING_MODULE
  167. );
  168. TestMonitor monitor = new TestMonitor();
  169. Injector injector = createInjector(ImmutableMap.of(), applicationDefaults, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  170. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  171. monitor.assertNumberOfErrors(0);
  172. monitor.assertNumberOfWarnings(0);
  173. assertNotNull(annotatedSetter);
  174. assertEquals(annotatedSetter.getStringValue(), "some value");
  175. assertEquals(annotatedSetter.isBooleanValue(), false);
  176. }
  177. @Test
  178. public void testPropertiesOverrideApplicationDefaults()
  179. {
  180. Map<String, String> properties = ImmutableMap.of(
  181. "string-value", "some value",
  182. "boolean-value", "false"
  183. );
  184. Map<String, String> applicationDefaults = ImmutableMap.of(
  185. "string-value", "some default value",
  186. "boolean-value", "true"
  187. );
  188. TestMonitor monitor = new TestMonitor();
  189. Injector injector = createInjector(properties, applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  190. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  191. monitor.assertNumberOfErrors(0);
  192. monitor.assertNumberOfWarnings(0);
  193. assertNotNull(annotatedSetter);
  194. assertEquals(annotatedSetter.getStringValue(), "some value");
  195. assertEquals(annotatedSetter.isBooleanValue(), false);
  196. }
  197. @Test
  198. public void testConfigurationDespiteLegacyConfig()
  199. {
  200. Map<String, String> properties = new TreeMap<>();
  201. properties.put("string-a", "this is a");
  202. properties.put("string-b", "this is b");
  203. TestMonitor monitor = new TestMonitor();
  204. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  205. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  206. monitor.assertNumberOfErrors(0);
  207. monitor.assertNumberOfWarnings(0);
  208. assertNotNull(legacyConfigPresent);
  209. assertEquals(legacyConfigPresent.getStringA(), "this is a");
  210. assertEquals(legacyConfigPresent.getStringB(), "this is b");
  211. }
  212. @Test
  213. public void testConfigurationThroughLegacyConfig()
  214. {
  215. Map<String, String> properties = new TreeMap<>();
  216. properties.put("string-value", "this is a");
  217. properties.put("string-b", "this is b");
  218. TestMonitor monitor = new TestMonitor();
  219. Injector injector = createInjector(properties, null, null, null, monitor,
  220. binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  221. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  222. monitor.assertNumberOfErrors(0);
  223. monitor.assertNumberOfWarnings(1);
  224. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  225. assertNotNull(legacyConfigPresent);
  226. assertEquals(legacyConfigPresent.getStringA(), "this is a");
  227. assertEquals(legacyConfigPresent.getStringB(), "this is b");
  228. }
  229. @Test
  230. public void testConfigurationWithPrefixThroughLegacyConfig()
  231. {
  232. Map<String, String> properties = new TreeMap<>();
  233. properties.put("example.string-value", "this is a");
  234. properties.put("example.string-b", "this is b");
  235. TestMonitor monitor = new TestMonitor();
  236. Injector injector = createInjector(properties, null, null, null, monitor,
  237. binder -> bindConfig(binder).bind(LegacyConfigPresent.class).prefixedWith("example"));
  238. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  239. monitor.assertNumberOfErrors(0);
  240. monitor.assertNumberOfWarnings(1);
  241. monitor.assertMatchingWarningRecorded("Configuration property 'example.string-value' has been replaced. Use 'example.string-a' instead.");
  242. assertNotNull(legacyConfigPresent);
  243. assertEquals(legacyConfigPresent.getStringA(), "this is a");
  244. assertEquals(legacyConfigPresent.getStringB(), "this is b");
  245. }
  246. @Test
  247. public void testConfigurationThroughLegacyConfigOverridesModuleDefaults()
  248. {
  249. Map<String, String> properties = ImmutableMap.of(
  250. "string-value", "this is a",
  251. "string-b", "this is b"
  252. );
  253. Map<String, String> moduleDefaults = ImmutableMap.of(
  254. "string-a", "some default value",
  255. "string-b", "some other default value"
  256. );
  257. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  258. "string-a", TEST_DEFAULTING_MODULE,
  259. "string-b", TEST_DEFAULTING_MODULE
  260. );
  261. TestMonitor monitor = new TestMonitor();
  262. Injector injector = createInjector(properties, null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  263. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  264. monitor.assertNumberOfErrors(0);
  265. monitor.assertNumberOfWarnings(1);
  266. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  267. assertNotNull(legacyConfigPresent);
  268. assertEquals(legacyConfigPresent.getStringA(), "this is a");
  269. assertEquals(legacyConfigPresent.getStringB(), "this is b");
  270. }
  271. @Test
  272. public void testConfigurationThroughLegacyConfigOverridesApplicationDefaults()
  273. {
  274. Map<String, String> properties = ImmutableMap.of(
  275. "string-value", "this is a",
  276. "string-b", "this is b"
  277. );
  278. Map<String, String> applicationDefaults = ImmutableMap.of(
  279. "string-a", "some default value",
  280. "string-b", "some other default value"
  281. );
  282. TestMonitor monitor = new TestMonitor();
  283. Injector injector = createInjector(properties, applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  284. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  285. monitor.assertNumberOfErrors(0);
  286. monitor.assertNumberOfWarnings(1);
  287. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  288. assertNotNull(legacyConfigPresent);
  289. assertEquals(legacyConfigPresent.getStringA(), "this is a");
  290. assertEquals(legacyConfigPresent.getStringB(), "this is b");
  291. }
  292. @Test
  293. public void testConfigurationWithRedundantLegacyConfigThrows()
  294. {
  295. Map<String, String> properties = new TreeMap<>();
  296. properties.put("string-value", "this is a");
  297. properties.put("string-a", "this is a");
  298. properties.put("string-b", "this is b");
  299. TestMonitor monitor = new TestMonitor();
  300. try {
  301. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  302. fail("Expected an exception in object creation due to use of conflicting configuration");
  303. }
  304. catch (CreationException e) {
  305. monitor.assertNumberOfErrors(1);
  306. monitor.assertNumberOfWarnings(1);
  307. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  308. assertContainsAllOf(e.getMessage(), "string-value", "conflicts with property", "string-a");
  309. }
  310. }
  311. @Test
  312. public void testConfigurationWithRedundantDeprecatedConfigThrows()
  313. {
  314. Map<String, String> properties = new TreeMap<>();
  315. properties.put("string-value", "this is a");
  316. properties.put("deprecated-string-value", "this is a");
  317. properties.put("string-b", "this is b");
  318. TestMonitor monitor = new TestMonitor();
  319. try {
  320. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  321. fail("Expected an exception in object creation due to use of conflicting configuration");
  322. }
  323. catch (CreationException e) {
  324. monitor.assertNumberOfErrors(1);
  325. monitor.assertNumberOfWarnings(2);
  326. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  327. monitor.assertMatchingWarningRecorded("deprecated-string-value", "replaced", "Use 'string-a'");
  328. assertContainsAllOf(e.getMessage(), "string-value", "conflicts with property", "deprecated-string-value");
  329. }
  330. }
  331. @Test
  332. public void testConfigurationWithConflictingLegacyConfigThrows()
  333. {
  334. Map<String, String> properties = new TreeMap<>();
  335. properties.put("string-value", "this is the old value");
  336. properties.put("string-a", "this is a");
  337. properties.put("string-b", "this is b");
  338. TestMonitor monitor = new TestMonitor();
  339. try {
  340. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  341. fail("Expected an exception in object creation due to conflicting configuration");
  342. }
  343. catch (CreationException e) {
  344. monitor.assertNumberOfErrors(1);
  345. monitor.assertNumberOfWarnings(1);
  346. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  347. assertContainsAllOf(e.getMessage(), "string-value", "conflicts with property", "string-a");
  348. }
  349. }
  350. @Test
  351. public void testLegacyModuleDefaultsThrows()
  352. {
  353. Map<String, String> moduleDefaults = ImmutableMap.of(
  354. "string-value", "some default value",
  355. "string-b", "some other default value"
  356. );
  357. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  358. "string-value", TEST_DEFAULTING_MODULE,
  359. "string-b", TEST_DEFAULTING_MODULE
  360. );
  361. TestMonitor monitor = new TestMonitor();
  362. try {
  363. createInjector(ImmutableMap.of(), null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  364. fail("Expected an exception in object creation due to conflicting configuration");
  365. }
  366. catch (CreationException e) {
  367. monitor.assertNumberOfErrors(1);
  368. monitor.assertNumberOfWarnings(0);
  369. assertContainsAllOf(e.getMessage(), "Module default property", "string-value", "(from testing module) has been replaced", "string-a");
  370. }
  371. }
  372. @Test
  373. public void testLegacyApplicationDefaultsThrows()
  374. {
  375. Map<String, String> applicationDefaults = ImmutableMap.of(
  376. "string-value", "some default value",
  377. "string-b", "some other default value"
  378. );
  379. TestMonitor monitor = new TestMonitor();
  380. try {
  381. createInjector(ImmutableMap.of(), applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(LegacyConfigPresent.class));
  382. fail("Expected an exception in object creation due to conflicting configuration");
  383. }
  384. catch (CreationException e) {
  385. monitor.assertNumberOfErrors(1);
  386. monitor.assertNumberOfWarnings(0);
  387. assertContainsAllOf(e.getMessage(), "Application default property", "string-value", "has been replaced", "string-a");
  388. }
  389. }
  390. @Test
  391. public void testConfigurationDespiteDeprecatedConfig()
  392. {
  393. Map<String, String> properties = new TreeMap<>();
  394. properties.put("string-b", "this is b");
  395. TestMonitor monitor = new TestMonitor();
  396. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(DeprecatedConfigPresent.class));
  397. DeprecatedConfigPresent deprecatedConfigPresent = injector.getInstance(DeprecatedConfigPresent.class);
  398. monitor.assertNumberOfErrors(0);
  399. monitor.assertNumberOfWarnings(0);
  400. assertNotNull(deprecatedConfigPresent);
  401. assertEquals(deprecatedConfigPresent.getStringA(), "defaultA");
  402. assertEquals(deprecatedConfigPresent.getStringB(), "this is b");
  403. }
  404. @Test
  405. public void testConfigurationThroughDeprecatedConfig()
  406. {
  407. Map<String, String> properties = new TreeMap<>();
  408. properties.put("string-a", "this is a");
  409. properties.put("string-b", "this is b");
  410. TestMonitor monitor = new TestMonitor();
  411. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(DeprecatedConfigPresent.class));
  412. DeprecatedConfigPresent deprecatedConfigPresent = injector.getInstance(DeprecatedConfigPresent.class);
  413. monitor.assertNumberOfErrors(0);
  414. monitor.assertNumberOfWarnings(1);
  415. monitor.assertMatchingWarningRecorded("string-a", "deprecated and should not be used");
  416. assertNotNull(deprecatedConfigPresent);
  417. assertEquals(deprecatedConfigPresent.getStringA(), "this is a");
  418. assertEquals(deprecatedConfigPresent.getStringB(), "this is b");
  419. }
  420. @Test
  421. public void testModuleDefaultsThroughDeprecatedConfig()
  422. {
  423. Map<String, String> moduleDefaults = ImmutableMap.of(
  424. "string-a", "this is a",
  425. "string-b", "this is b"
  426. );
  427. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  428. "string-a", TEST_DEFAULTING_MODULE,
  429. "string-b", TEST_DEFAULTING_MODULE
  430. );
  431. TestMonitor monitor = new TestMonitor();
  432. Injector injector = createInjector(ImmutableMap.of(), null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(DeprecatedConfigPresent.class));
  433. DeprecatedConfigPresent deprecatedConfigPresent = injector.getInstance(DeprecatedConfigPresent.class);
  434. monitor.assertNumberOfErrors(0);
  435. monitor.assertNumberOfWarnings(0);
  436. assertNotNull(deprecatedConfigPresent);
  437. assertEquals(deprecatedConfigPresent.getStringA(), "this is a");
  438. assertEquals(deprecatedConfigPresent.getStringB(), "this is b");
  439. }
  440. @Test
  441. public void testApplicationDefaultsThroughDeprecatedConfig()
  442. {
  443. Map<String, String> applicationDefaults = ImmutableMap.of(
  444. "string-a", "this is a",
  445. "string-b", "this is b"
  446. );
  447. TestMonitor monitor = new TestMonitor();
  448. Injector injector = createInjector(ImmutableMap.of(), applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(DeprecatedConfigPresent.class));
  449. DeprecatedConfigPresent deprecatedConfigPresent = injector.getInstance(DeprecatedConfigPresent.class);
  450. monitor.assertNumberOfErrors(0);
  451. monitor.assertNumberOfWarnings(0);
  452. assertNotNull(deprecatedConfigPresent);
  453. assertEquals(deprecatedConfigPresent.getStringA(), "this is a");
  454. assertEquals(deprecatedConfigPresent.getStringB(), "this is b");
  455. }
  456. @Test
  457. public void testDefunctPropertyInConfigThrows()
  458. {
  459. Map<String, String> properties = new TreeMap<>();
  460. properties.put("string-value", "this is a");
  461. properties.put("defunct-value", "this shouldn't work");
  462. TestMonitor monitor = new TestMonitor();
  463. try {
  464. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(DefunctConfigPresent.class));
  465. fail("Expected an exception in object creation due to use of defunct config");
  466. }
  467. catch (CreationException e) {
  468. monitor.assertNumberOfErrors(1);
  469. monitor.assertNumberOfWarnings(0);
  470. monitor.assertMatchingErrorRecorded("Defunct property", "'defunct-value", "cannot be configured");
  471. }
  472. }
  473. @Test
  474. public void testDefunctPropertyInModuleDefaultsThrows()
  475. {
  476. Map<String, String> moduleDefaults = ImmutableMap.of(
  477. "string-value", "this is a",
  478. "defunct-value", "this shouldn't work"
  479. );
  480. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  481. "string-value", TEST_DEFAULTING_MODULE,
  482. "defunct-value", TEST_DEFAULTING_MODULE
  483. );
  484. TestMonitor monitor = new TestMonitor();
  485. try {
  486. createInjector(ImmutableMap.of(), null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(DefunctConfigPresent.class));
  487. fail("Expected an exception in object creation due to use of defunct config");
  488. }
  489. catch (CreationException e) {
  490. monitor.assertNumberOfErrors(1);
  491. monitor.assertNumberOfWarnings(0);
  492. monitor.assertMatchingErrorRecorded("Defunct property", "'defunct-value", "cannot have a module default (from testing module)");
  493. }
  494. }
  495. @Test
  496. public void testDefunctPropertyInApplicationDefaultsThrows()
  497. {
  498. Map<String, String> applicationDefaults = ImmutableMap.of(
  499. "string-value", "this is a",
  500. "defunct-value", "this shouldn't work"
  501. );
  502. TestMonitor monitor = new TestMonitor();
  503. try {
  504. createInjector(ImmutableMap.of(), applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(DefunctConfigPresent.class));
  505. fail("Expected an exception in object creation due to use of defunct config");
  506. }
  507. catch (CreationException e) {
  508. monitor.assertNumberOfErrors(1);
  509. monitor.assertNumberOfWarnings(0);
  510. monitor.assertMatchingErrorRecorded("Defunct property", "'defunct-value", "cannot have an application default");
  511. }
  512. }
  513. @Test
  514. public void testNoCoerceValueThrows()
  515. {
  516. Map<String, String> properties = new HashMap<>();
  517. properties.put("string-value", "has a value");
  518. properties.put("int-value", "not a number");
  519. TestMonitor monitor = new TestMonitor();
  520. try {
  521. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(BeanValidationClass.class));
  522. fail("Expected an exception in object creation due to coercion failure");
  523. }
  524. catch (CreationException e) {
  525. monitor.assertNumberOfErrors(1);
  526. monitor.assertNumberOfWarnings(0);
  527. monitor.assertMatchingErrorRecorded("Could not coerce value 'not a number' to int", "'int-value'", "in order to call", "BeanValidationClass.setIntValue(int)");
  528. }
  529. }
  530. @Test
  531. public void testNoCoerceBoolValueThrows()
  532. {
  533. Map<String, String> properties = new HashMap<>();
  534. properties.put("string-value", "has a value");
  535. properties.put("boolean-value", "not a boolean");
  536. TestMonitor monitor = new TestMonitor();
  537. try {
  538. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(AnnotatedSetter.class));
  539. fail("Expected an exception in object creation due to coercion failure");
  540. }
  541. catch (CreationException e) {
  542. monitor.assertNumberOfErrors(1);
  543. monitor.assertNumberOfWarnings(0);
  544. monitor.assertMatchingErrorRecorded("Could not coerce value 'not a boolean' to boolean", "'boolean-value'", "in order to call", "AnnotatedSetter.setBooleanValue(boolean)");
  545. }
  546. }
  547. @Test
  548. public void testSuccessfulBeanValidation()
  549. {
  550. Map<String, String> properties = new HashMap<>();
  551. properties.put("string-value", "has a value");
  552. properties.put("int-value", "50");
  553. TestMonitor monitor = new TestMonitor();
  554. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(BeanValidationClass.class));
  555. BeanValidationClass beanValidationClass = injector.getInstance(BeanValidationClass.class);
  556. monitor.assertNumberOfErrors(0);
  557. monitor.assertNumberOfWarnings(0);
  558. assertNotNull(beanValidationClass);
  559. assertEquals(beanValidationClass.getStringValue(), "has a value");
  560. assertEquals(beanValidationClass.getIntValue(), 50);
  561. }
  562. @Test
  563. public void testFailedBeanValidationThrows()
  564. {
  565. Map<String, String> properties = ImmutableMap.of(
  566. // string-value left at invalid default
  567. "int-value", "5000" // out of range
  568. );
  569. TestMonitor monitor = new TestMonitor();
  570. try {
  571. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(BeanValidationClass.class));
  572. fail("Expected an exception in object creation due to bean validation failure");
  573. }
  574. catch (CreationException e) {
  575. monitor.assertNumberOfErrors(2);
  576. monitor.assertNumberOfWarnings(0);
  577. monitor.assertMatchingErrorRecorded("Invalid configuration property", "'int-value'", "must be less than or equal to 100", "BeanValidationClass");
  578. monitor.assertMatchingErrorRecorded("Missing required configuration property", "'string-value'", "BeanValidationClass");
  579. }
  580. }
  581. @Test
  582. public void testMapModuleDefaultsThrows()
  583. {
  584. Map<String, String> moduleDefaults = ImmutableMap.of(
  585. "map-a.k3", "this is a"
  586. );
  587. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  588. "map-a.k3", TEST_DEFAULTING_MODULE
  589. );
  590. TestMonitor monitor = new TestMonitor();
  591. try {
  592. createInjector(ImmutableMap.of(), null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(MapConfigPresent.class));
  593. fail("Expected an exception in object creation due to use of application default for map config");
  594. }
  595. catch (CreationException e) {
  596. monitor.assertNumberOfErrors(1);
  597. monitor.assertNumberOfWarnings(0);
  598. assertContainsAllOf(e.getMessage(), "Cannot have module default property", "map-a.k3", "(from testing module) for a configuration map");
  599. }
  600. }
  601. @Test
  602. public void testMapValueModuleDefaultsThrows()
  603. {
  604. Map<String, String> moduleDefaults = ImmutableMap.of(
  605. "map-b.k3.string-value", "this is a"
  606. );
  607. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  608. "map-b.k3.string-value", TEST_DEFAULTING_MODULE
  609. );
  610. TestMonitor monitor = new TestMonitor();
  611. try {
  612. createInjector(ImmutableMap.of(), null, moduleDefaults, moduleDefaultSource, monitor, binder -> bindConfig(binder).bind(MapConfigPresent.class));
  613. fail("Expected an exception in object creation due to use of application default for map config");
  614. }
  615. catch (CreationException e) {
  616. monitor.assertNumberOfErrors(1);
  617. monitor.assertNumberOfWarnings(0);
  618. assertContainsAllOf(e.getMessage(), "Cannot have module default property", "map-b.k3.string-value", "(from testing module) for a configuration map");
  619. }
  620. }
  621. @Test
  622. public void testMapApplicationDefaultsThrows()
  623. {
  624. Map<String, String> applicationDefaults = ImmutableMap.of(
  625. "map-a.k3", "this is a"
  626. );
  627. TestMonitor monitor = new TestMonitor();
  628. try {
  629. createInjector(ImmutableMap.of(), applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(MapConfigPresent.class));
  630. fail("Expected an exception in object creation due to use of application default for map config");
  631. }
  632. catch (CreationException e) {
  633. monitor.assertNumberOfErrors(1);
  634. monitor.assertNumberOfWarnings(0);
  635. assertContainsAllOf(e.getMessage(), "Cannot have application default property", "map-a.k3", "for a configuration map");
  636. }
  637. }
  638. @Test
  639. public void testMapValueApplicationDefaultsThrows()
  640. {
  641. Map<String, String> applicationDefaults = ImmutableMap.of(
  642. "map-b.k3.string-value", "this is a"
  643. );
  644. TestMonitor monitor = new TestMonitor();
  645. try {
  646. createInjector(ImmutableMap.of(), applicationDefaults, null, null, monitor, binder -> bindConfig(binder).bind(MapConfigPresent.class));
  647. fail("Expected an exception in object creation due to use of application default for map config");
  648. }
  649. catch (CreationException e) {
  650. monitor.assertNumberOfErrors(1);
  651. monitor.assertNumberOfWarnings(0);
  652. assertContainsAllOf(e.getMessage(), "Cannot have application default property", "map-b.k3.string-value", "for a configuration map");
  653. }
  654. }
  655. @Test
  656. public void testConfigurationThroughLegacyMapConfig()
  657. {
  658. Map<String, String> properties = new TreeMap<>();
  659. properties.put("map-value.k", "this is a");
  660. properties.put("map-b.k2", "this is b");
  661. TestMonitor monitor = new TestMonitor();
  662. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyMapConfigPresent.class));
  663. LegacyMapConfigPresent legacyMapConfigPresent = injector.getInstance(LegacyMapConfigPresent.class);
  664. monitor.assertNumberOfErrors(0);
  665. monitor.assertNumberOfWarnings(1);
  666. monitor.assertMatchingWarningRecorded("map-value", "replaced", "Use 'map-a'");
  667. assertNotNull(legacyMapConfigPresent);
  668. assertEquals(legacyMapConfigPresent.getMapA(), ImmutableMap.of("k", "this is a"));
  669. assertEquals(legacyMapConfigPresent.getMapB(), ImmutableMap.of("k2", "this is b"));
  670. }
  671. @Test
  672. public void testConfigurationWithRedundantLegacyMapConfigThrows()
  673. {
  674. Map<String, String> properties = new TreeMap<>();
  675. properties.put("map-value.k", "this is a");
  676. properties.put("map-a.k3", "this is a");
  677. properties.put("map-b.k2", "this is b");
  678. TestMonitor monitor = new TestMonitor();
  679. try {
  680. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyMapConfigPresent.class));
  681. fail("Expected an exception in object creation due to use of conflicting configuration");
  682. }
  683. catch (CreationException e) {
  684. monitor.assertNumberOfErrors(1);
  685. monitor.assertNumberOfWarnings(1);
  686. monitor.assertMatchingWarningRecorded("map-value", "replaced", "Use 'map-a'");
  687. assertContainsAllOf(e.getMessage(), "map-value", "conflicts with map property prefix", "map-a");
  688. }
  689. }
  690. @Test
  691. public void testConfigurationWithRedundantDeprecatedMapConfigThrows()
  692. {
  693. Map<String, String> properties = ImmutableMap.of(
  694. "map-value.k", "this is a",
  695. "deprecated-map-value.k3", "this is a",
  696. "map-b.k2", "this is b"
  697. );
  698. TestMonitor monitor = new TestMonitor();
  699. try {
  700. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyMapConfigPresent.class));
  701. fail("Expected an exception in object creation due to use of conflicting configuration");
  702. }
  703. catch (CreationException e) {
  704. monitor.assertNumberOfErrors(1);
  705. monitor.assertNumberOfWarnings(2);
  706. monitor.assertMatchingWarningRecorded("map-value", "replaced", "Use 'map-a'");
  707. monitor.assertMatchingWarningRecorded("deprecated-map-value", "replaced", "Use 'map-a'");
  708. assertContainsAllOf(e.getMessage(), "map-value", "conflicts with map property prefix", "deprecated-map-value");
  709. }
  710. }
  711. @Test
  712. public void testConfigurationThroughDeprecatedMapConfig()
  713. {
  714. Map<String, String> properties = new TreeMap<>();
  715. properties.put("map-a.k1", "this is a");
  716. properties.put("map-b.k2", "this is b");
  717. TestMonitor monitor = new TestMonitor();
  718. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(DeprecatedMapConfigPresent.class));
  719. DeprecatedMapConfigPresent deprecatedMapConfigPresent = injector.getInstance(DeprecatedMapConfigPresent.class);
  720. monitor.assertNumberOfErrors(0);
  721. monitor.assertNumberOfWarnings(1);
  722. monitor.assertMatchingWarningRecorded("map-a", "deprecated and should not be used");
  723. assertNotNull(deprecatedMapConfigPresent);
  724. assertEquals(deprecatedMapConfigPresent.getMapA(), ImmutableMap.of("k1", "this is a"));
  725. assertEquals(deprecatedMapConfigPresent.getMapB(), ImmutableMap.of("k2", "this is b"));
  726. }
  727. @Test
  728. public void testConfigurationThroughLegacyMapValueConfig()
  729. {
  730. Map<String, String> properties = new TreeMap<>();
  731. properties.put("map-a.k.string-value", "this is a");
  732. properties.put("map-a.k.string-b", "this is b");
  733. TestMonitor monitor = new TestMonitor();
  734. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyMapValueConfigPresent.class));
  735. LegacyMapValueConfigPresent legacyMapValueConfigPresent = injector.getInstance(LegacyMapValueConfigPresent.class);
  736. monitor.assertNumberOfErrors(0);
  737. monitor.assertNumberOfWarnings(1);
  738. monitor.assertMatchingWarningRecorded("map-a.k.string-value", "replaced", "Use 'map-a.k.string-a'");
  739. assertNotNull(legacyMapValueConfigPresent);
  740. assertEquals(legacyMapValueConfigPresent.getMapA().get("k").getStringA(), "this is a");
  741. assertEquals(legacyMapValueConfigPresent.getMapA().get("k").getStringB(), "this is b");
  742. }
  743. @Test
  744. public void testConfigurationWithRedundantLegacyMapValueConfigThrows()
  745. {
  746. Map<String, String> properties = new TreeMap<>();
  747. properties.put("map-a.k.string-value", "this is a");
  748. properties.put("map-a.k.string-a", "this is a");
  749. properties.put("map-a.k.string-b", "this is b");
  750. TestMonitor monitor = new TestMonitor();
  751. try {
  752. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyMapValueConfigPresent.class));
  753. fail("Expected an exception in object creation due to use of conflicting configuration");
  754. }
  755. catch (CreationException e) {
  756. monitor.assertNumberOfErrors(1);
  757. monitor.assertNumberOfWarnings(1);
  758. monitor.assertMatchingWarningRecorded("map-a.k.string-value", "replaced", "Use 'map-a.k.string-a'");
  759. assertContainsAllOf(e.getMessage(), "map-a.k.string-value", "conflicts with property", "map-a.k.string-a");
  760. }
  761. }
  762. @Test
  763. public void testConfigurationWithRedundantDeprecatedMapValueConfigThrows()
  764. {
  765. Map<String, String> properties = new TreeMap<>();
  766. properties.put("map-a.k.string-value", "this is a");
  767. properties.put("map-a.k.deprecated-string-value", "this is a");
  768. properties.put("map-a.k.string-b", "this is b");
  769. TestMonitor monitor = new TestMonitor();
  770. try {
  771. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(LegacyMapValueConfigPresent.class));
  772. fail("Expected an exception in object creation due to use of conflicting configuration");
  773. }
  774. catch (CreationException e) {
  775. monitor.assertNumberOfErrors(1);
  776. monitor.assertNumberOfWarnings(2);
  777. monitor.assertMatchingWarningRecorded("map-a.k.string-value", "replaced", "Use 'map-a.k.string-a'");
  778. monitor.assertMatchingWarningRecorded("map-a.k.deprecated-string-value", "replaced", "Use 'map-a.k.string-a'");
  779. assertContainsAllOf(e.getMessage(), "map-a.k.string-value", "conflicts with property", "map-a.k.deprecated-string-value");
  780. }
  781. }
  782. @Test
  783. public void testConfigurationThroughDeprecatedMapValueConfig()
  784. {
  785. Map<String, String> properties = new TreeMap<>();
  786. properties.put("map-a.k.string-a", "this is a");
  787. properties.put("map-a.k.string-b", "this is b");
  788. TestMonitor monitor = new TestMonitor();
  789. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(DeprecatedMapValueConfigPresent.class));
  790. DeprecatedMapValueConfigPresent deprecatedMapValueConfigPresent = injector.getInstance(DeprecatedMapValueConfigPresent.class);
  791. monitor.assertNumberOfErrors(0);
  792. monitor.assertNumberOfWarnings(1);
  793. monitor.assertMatchingWarningRecorded("map-a.k.string-a", "deprecated and should not be used");
  794. assertNotNull(deprecatedMapValueConfigPresent);
  795. assertEquals(deprecatedMapValueConfigPresent.getMapA().get("k").getStringA(), "this is a");
  796. assertEquals(deprecatedMapValueConfigPresent.getMapA().get("k").getStringB(), "this is b");
  797. }
  798. @Test
  799. public void testDefunctPropertyInMapValueConfigThrows()
  800. {
  801. Map<String, String> properties = new TreeMap<>();
  802. properties.put("map-a.k.string-value", "this is a");
  803. properties.put("map-a.k.defunct-value", "this shouldn't work");
  804. TestMonitor monitor = new TestMonitor();
  805. try {
  806. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(DefunctMapValueConfigPresent.class));
  807. fail("Expected an exception in object creation due to use of defunct config");
  808. }
  809. catch (CreationException e) {
  810. monitor.assertNumberOfErrors(1);
  811. monitor.assertNumberOfWarnings(0);
  812. monitor.assertMatchingErrorRecorded("Defunct property", "'map-a.k.defunct-value", "cannot be configured");
  813. }
  814. }
  815. @Test
  816. public void testSuccessfulMapValueBeanValidation()
  817. {
  818. Map<String, String> properties = new HashMap<>();
  819. properties.put("map-a.k.string-value", "has a value");
  820. properties.put("map-a.k.int-value", "50");
  821. TestMonitor monitor = new TestMonitor();
  822. Injector injector = createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(MapValueBeanValidationClass.class));
  823. MapValueBeanValidationClass mapValueBeanValidationClass = injector.getInstance(MapValueBeanValidationClass.class);
  824. monitor.assertNumberOfErrors(0);
  825. monitor.assertNumberOfWarnings(0);
  826. assertNotNull(mapValueBeanValidationClass);
  827. assertEquals(mapValueBeanValidationClass.getMapA().get("k").getStringValue(), "has a value");
  828. assertEquals(mapValueBeanValidationClass.getMapA().get("k").getIntValue(), 50);
  829. }
  830. @Test
  831. public void testFailedMapValueBeanValidation()
  832. {
  833. Map<String, String> properties = new HashMap<>();
  834. // string-value left at invalid default
  835. properties.put("map-a.k.int-value", "5000"); // out of range
  836. TestMonitor monitor = new TestMonitor();
  837. try {
  838. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(MapValueBeanValidationClass.class));
  839. }
  840. catch (CreationException e) {
  841. monitor.assertNumberOfErrors(2);
  842. monitor.assertNumberOfWarnings(0);
  843. monitor.assertMatchingErrorRecorded("Invalid configuration property", "'map-a.k.int-value'", "must be less than or equal to 100", "BeanValidationClass");
  844. monitor.assertMatchingErrorRecorded("Missing required configuration property", "'map-a.k.string-value'", "BeanValidationClass");
  845. }
  846. }
  847. @Test
  848. public void testConfigurationWithDifferentRepresentationOfSameMapKeyThrows()
  849. {
  850. Map<String, String> properties = new TreeMap<>();
  851. properties.put("map-a.01337.string-a", "this is a");
  852. properties.put("map-a.1337.string-b", "this is b");
  853. TestMonitor monitor = new TestMonitor();
  854. try {
  855. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(IntegerLegacyMapConfig.class));
  856. fail("Expected an exception in object creation due to use of conflicting configuration");
  857. }
  858. catch (CreationException e) {
  859. monitor.assertNumberOfErrors(1);
  860. monitor.assertNumberOfWarnings(0);
  861. assertContainsAllOf(e.getMessage(), "Configuration property prefixes", "'map-a.1337'", "'map-a.01337'", "convert to the same map key", "setMapA");
  862. }
  863. }
  864. @Test
  865. public void testConfigurationOfSimpleMapValueWithComplexPropertyThrows()
  866. {
  867. Map<String, String> properties = new TreeMap<>();
  868. properties.put("map-a.1337.string-a", "this is a");
  869. TestMonitor monitor = new TestMonitor();
  870. try {
  871. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(IntegerStringMapConfig.class));
  872. fail("Expected an exception in object creation due to use of invalid configuration");
  873. }
  874. catch (CreationException e) {
  875. monitor.assertNumberOfErrors(1);
  876. monitor.assertNumberOfWarnings(0);
  877. assertContainsAllOf(e.getMessage(), "Configuration map has non-configuration value class java.lang.String, so key '1337' cannot be followed by '.'",
  878. "property 'map-a.1337.string-a'", "setMapA");
  879. }
  880. }
  881. @Test
  882. public void testConfigurationWithInvalidMapKeyThrows()
  883. {
  884. Map<String, String> properties = new TreeMap<>();
  885. properties.put("map-a.k.string-a", "this is a");
  886. TestMonitor monitor = new TestMonitor();
  887. try {
  888. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(IntegerLegacyMapConfig.class));
  889. fail("Expected an exception in object creation due to use of invalid configuration");
  890. }
  891. catch (CreationException e) {
  892. monitor.assertNumberOfErrors(1);
  893. monitor.assertNumberOfWarnings(0);
  894. assertContainsAllOf(e.getMessage(), "Could not coerce map key 'k' to java.lang.Integer", "property prefix 'map-a.k'", "setMapA");
  895. }
  896. }
  897. @Test
  898. public void testFailedCoercion()
  899. {
  900. Map<String, String> properties = new HashMap<>();
  901. properties.put("int-value", "abc %s xyz"); // not an int
  902. TestMonitor monitor = new TestMonitor();
  903. try {
  904. createInjector(properties, null, null, null, monitor, binder -> bindConfig(binder).bind(BeanValidationClass.class));
  905. }
  906. catch (CreationException e) {
  907. monitor.assertNumberOfErrors(1);
  908. monitor.assertNumberOfWarnings(0);
  909. monitor.assertMatchingErrorRecorded("Could not coerce value 'abc %s xyz' to int (property 'int-value')", "BeanValidationClass");
  910. }
  911. }
  912. private Injector createInjector(Map<String, String> properties, Map<String, String> applicationDefaults, Map<String, String> moduleDefaults, Map<String, ConfigurationDefaultingModule> moduleDefaultSource, TestMonitor monitor, Module module)
  913. {
  914. ConfigurationFactory configurationFactory = new ConfigurationFactory(
  915. properties,
  916. firstNonNull(applicationDefaults, ImmutableMap.of()),
  917. firstNonNull(moduleDefaults, ImmutableMap.of()),
  918. firstNonNull(moduleDefaultSource, ImmutableMap.of()),
  919. Collections.emptySet(),
  920. ImmutableList.of(),
  921. monitor);
  922. List<Message> messages = new ConfigurationValidator(configurationFactory).validate(module);
  923. return Guice.createInjector(new ConfigurationModule(configurationFactory), module, new ValidationErrorModule(messages));
  924. }
  925. public static class AnnotatedGetter
  926. {
  927. private String stringValue;
  928. private boolean booleanValue;
  929. @Config("string-value")
  930. public String getStringValue()
  931. {
  932. return stringValue;
  933. }
  934. public void setStringValue(String stringValue)
  935. {
  936. this.stringValue = stringValue;
  937. }
  938. @Config("boolean-value")
  939. public boolean isBooleanValue()
  940. {
  941. return booleanValue;
  942. }
  943. public void setBooleanValue(boolean booleanValue)
  944. {
  945. this.booleanValue = booleanValue;
  946. }
  947. }
  948. static class AnnotatedSetter
  949. {
  950. private String stringValue;
  951. private boolean booleanValue;
  952. String getStringValue()
  953. {
  954. return stringValue;
  955. }
  956. @Config("string-value")
  957. void setStringValue(String stringValue)
  958. {
  959. this.stringValue = stringValue;
  960. }
  961. private boolean isBooleanValue()
  962. {
  963. return booleanValue;
  964. }
  965. @Config("boolean-value")
  966. private void setBooleanValue(boolean booleanValue)
  967. {
  968. this.booleanValue = booleanValue;
  969. }
  970. }
  971. private static class LegacyConfigPresent
  972. {
  973. private String stringA = "defaultA";
  974. private String stringB = "defaultB";
  975. String getStringA()
  976. {
  977. return stringA;
  978. }
  979. @Config("string-a")
  980. @LegacyConfig("string-value")
  981. private void setStringA(String stringValue)
  982. {
  983. this.stringA = stringValue;
  984. }
  985. @Deprecated
  986. @LegacyConfig(value = "deprecated-string-value", replacedBy = "string-a")
  987. private void setDeprecatedStringA(String stringValue)
  988. {
  989. this.stringA = stringValue;
  990. }
  991. private String getStringB()
  992. {
  993. return stringB;
  994. }
  995. @Config("string-b")
  996. public void setStringB(String stringValue)
  997. {
  998. this.stringB = stringValue;
  999. }
  1000. }
  1001. static class DeprecatedConfigPresent
  1002. {
  1003. private String stringA = "defaultA";
  1004. private String stringB = "defaultB";
  1005. @Deprecated
  1006. String getStringA()
  1007. {
  1008. return stringA;
  1009. }
  1010. @Deprecated
  1011. @Config("string-a")
  1012. void setStringA(String stringValue)
  1013. {
  1014. this.stringA = stringValue;
  1015. }
  1016. private String getStringB()
  1017. {
  1018. return stringB;
  1019. }
  1020. @Config("string-b")
  1021. private void setStringB(String stringValue)
  1022. {
  1023. this.stringB = stringValue;
  1024. }
  1025. }
  1026. @DefunctConfig("defunct-value