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

https://github.com/ssindkar/platform · Java · 357 lines · 328 code · 29 blank · 0 comment · 12 complexity · 9ea565bd8eeb28f7c71ea6b6c8517609 MD5 · raw file

  1. package com.proofpoint.configuration;
  2. import com.google.common.collect.ImmutableList;
  3. import com.google.common.collect.ImmutableMap;
  4. import com.google.common.collect.Iterators;
  5. import com.google.inject.Binder;
  6. import com.google.inject.Guice;
  7. import com.google.inject.Module;
  8. import com.google.inject.PrivateBinder;
  9. import com.google.inject.spi.Message;
  10. import com.proofpoint.configuration.ConfigurationFactoryTest.AnnotatedSetter;
  11. import com.proofpoint.configuration.ConfigurationFactoryTest.LegacyMapConfigPresent;
  12. import com.proofpoint.configuration.ConfigurationFactoryTest.LegacyMapValueConfigPresent;
  13. import com.proofpoint.configuration.ConfigurationInspector.ConfigAttribute;
  14. import com.proofpoint.configuration.ConfigurationInspector.ConfigRecord;
  15. import com.proofpoint.configuration.ConfigurationMetadataTest.SetterSensitiveClass;
  16. import org.testng.annotations.Test;
  17. import javax.inject.Qualifier;
  18. import java.lang.annotation.Retention;
  19. import java.lang.annotation.RetentionPolicy;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.SortedSet;
  24. import java.util.TreeMap;
  25. import static com.google.common.base.MoreObjects.firstNonNull;
  26. import static com.proofpoint.configuration.ConfigBinder.bindConfig;
  27. import static org.testng.Assert.assertEquals;
  28. import static org.testng.Assert.fail;
  29. public class TestConfigurationInspector
  30. {
  31. private static final ConfigurationDefaultingModule TEST_DEFAULTING_MODULE = new ConfigurationDefaultingModule()
  32. {
  33. @Override
  34. public Map<String, String> getConfigurationDefaults()
  35. {
  36. throw new UnsupportedOperationException();
  37. }
  38. @Override
  39. public void configure(Binder binder)
  40. {
  41. throw new UnsupportedOperationException();
  42. }
  43. @Override
  44. public String toString()
  45. {
  46. return "testing module";
  47. }
  48. };
  49. private static final String PACKAGE_NAME = "com.proofpoint.configuration.";
  50. private static InspectionVerifier inspect(Map<String, String> properties, Map<String, String> applicationDefaults, Map<String, String> moduleDefaults, Map<String, ConfigurationDefaultingModule> moduleDefaultSource, Module module)
  51. {
  52. ConfigurationFactory configurationFactory = new ConfigurationFactory(
  53. properties,
  54. firstNonNull(applicationDefaults, ImmutableMap.of()),
  55. firstNonNull(moduleDefaults, ImmutableMap.of()),
  56. firstNonNull(moduleDefaultSource, ImmutableMap.of()),
  57. properties.keySet(),
  58. ImmutableList.of(),
  59. Problems.NULL_MONITOR
  60. );
  61. List<Message> messages = new ConfigurationValidator(configurationFactory).validate(module);
  62. InspectionVerifier verifier = new InspectionVerifier(new ConfigurationInspector().inspect(configurationFactory));
  63. Guice.createInjector(new ConfigurationModule(configurationFactory), module, new ValidationErrorModule(messages));
  64. return verifier;
  65. }
  66. @Test
  67. public void testSimpleConfig()
  68. {
  69. Map<String, String> properties = new TreeMap<>();
  70. properties.put("string-value", "some value");
  71. properties.put("boolean-value", "true");
  72. inspect(properties, null, null, null, binder -> bindConfig(binder).bind(AnnotatedSetter.class))
  73. .component("ConfigurationFactoryTest$AnnotatedSetter")
  74. .value("BooleanValue", "boolean-value", "false", "true", "")
  75. .value("StringValue", "string-value", "null", "some value", "")
  76. .end();
  77. }
  78. @Test
  79. public void testPrefixedWithNotPrefixed()
  80. {
  81. Map<String, String> properties = new TreeMap<>();
  82. properties.put("string-value", "some value");
  83. properties.put("boolean-value", "true");
  84. properties.put("prefix.string-value", "some other value");
  85. properties.put("prefix.boolean-value", "false");
  86. inspect(properties, null, null, null,
  87. binder -> {
  88. bindConfig(binder).bind(AnnotatedSetter.class);
  89. bindConfig(binder).bind(AnnotatedSetter.class).annotatedWith(Prefixed.class).prefixedWith("prefix");
  90. })
  91. .component("ConfigurationFactoryTest$AnnotatedSetter")
  92. .value("BooleanValue", "boolean-value", "false", "true", "")
  93. .value("StringValue", "string-value", "null", "some value", "")
  94. .component("@Prefixed", "ConfigurationFactoryTest$AnnotatedSetter")
  95. .value("BooleanValue", "prefix.boolean-value", "false", "false", "")
  96. .value("StringValue", "prefix.string-value", "null", "some other value", "")
  97. .end();
  98. }
  99. @Test
  100. public void testSimpleConfigWithModuleDefaults()
  101. {
  102. Map<String, String> properties = ImmutableMap.of(
  103. "string-value", "some value",
  104. "boolean-value", "false"
  105. );
  106. Map<String, String> moduleDefaults = ImmutableMap.of(
  107. "string-value", "some default value",
  108. "boolean-value", "true"
  109. );
  110. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  111. "string-value", TEST_DEFAULTING_MODULE,
  112. "boolean-value", TEST_DEFAULTING_MODULE
  113. );
  114. inspect(properties, null, moduleDefaults, moduleDefaultSource, binder -> bindConfig(binder).bind(AnnotatedSetter.class))
  115. .component("ConfigurationFactoryTest$AnnotatedSetter")
  116. .value("BooleanValue", "boolean-value", "true", "false", "")
  117. .value("StringValue", "string-value", "some default value", "some value", "")
  118. .end();
  119. }
  120. @Test
  121. public void testSimpleConfigWithApplicationDefaults()
  122. {
  123. Map<String, String> properties = ImmutableMap.of(
  124. "string-value", "some value",
  125. "boolean-value", "false"
  126. );
  127. Map<String, String> applicationDefaults = ImmutableMap.of(
  128. "string-value", "some default value",
  129. "boolean-value", "true"
  130. );
  131. inspect(properties, applicationDefaults, null, null, binder -> bindConfig(binder).bind(AnnotatedSetter.class))
  132. .component("ConfigurationFactoryTest$AnnotatedSetter")
  133. .value("BooleanValue", "boolean-value", "true", "false", "")
  134. .value("StringValue", "string-value", "some default value", "some value", "")
  135. .end();
  136. }
  137. @Test
  138. public void testSimpleConfigWithModuleAndApplicationDefaults()
  139. {
  140. Map<String, String> properties = ImmutableMap.of(
  141. "string-value", "some value",
  142. "boolean-value", "false"
  143. );
  144. Map<String, String> applicationDefaults = ImmutableMap.of(
  145. "string-value", "some default value",
  146. "boolean-value", "true"
  147. );
  148. Map<String, String> moduleDefaults = ImmutableMap.of(
  149. "string-value", "some module default value",
  150. "boolean-value", "true"
  151. );
  152. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  153. "string-value", TEST_DEFAULTING_MODULE,
  154. "boolean-value", TEST_DEFAULTING_MODULE
  155. );
  156. inspect(properties, applicationDefaults, moduleDefaults, moduleDefaultSource, binder -> bindConfig(binder).bind(AnnotatedSetter.class))
  157. .component("ConfigurationFactoryTest$AnnotatedSetter")
  158. .value("BooleanValue", "boolean-value", "true", "false", "")
  159. .value("StringValue", "string-value", "some default value", "some value", "")
  160. .end();
  161. }
  162. @Test
  163. public void testSecuritySensitiveConfig()
  164. {
  165. Map<String, String> properties = new TreeMap<>();
  166. properties.put("value", "some value");
  167. inspect(properties, null, null, null, binder -> bindConfig(binder).bind(SetterSensitiveClass.class))
  168. .component("ConfigurationMetadataTest$SetterSensitiveClass")
  169. .value("Value", "value", "[REDACTED]", "[REDACTED]", "description")
  170. .end();
  171. }
  172. @Test
  173. public void testSecuritySensitiveConfigWithModuleDefaults()
  174. {
  175. Map<String, String> properties = ImmutableMap.of(
  176. "value", "some value"
  177. );
  178. Map<String, String> moduleDefaults = ImmutableMap.of(
  179. "value", "some default value"
  180. );
  181. Map<String, ConfigurationDefaultingModule> moduleDefaultSource = ImmutableMap.of(
  182. "value", TEST_DEFAULTING_MODULE
  183. );
  184. inspect(properties, null, moduleDefaults, moduleDefaultSource, binder -> bindConfig(binder).bind(SetterSensitiveClass.class))
  185. .component("ConfigurationMetadataTest$SetterSensitiveClass")
  186. .value("Value", "value", "[REDACTED]", "[REDACTED]", "description")
  187. .end();
  188. }
  189. @Test
  190. public void testSecuritySensitiveConfigWithApplicationDefaults()
  191. {
  192. Map<String, String> properties = ImmutableMap.of(
  193. "value", "some value"
  194. );
  195. Map<String, String> applicationDefaults = ImmutableMap.of(
  196. "value", "some default value"
  197. );
  198. inspect(properties, applicationDefaults, null, null, binder -> bindConfig(binder).bind(SetterSensitiveClass.class))
  199. .component("ConfigurationMetadataTest$SetterSensitiveClass")
  200. .value("Value", "value", "[REDACTED]", "[REDACTED]", "description")
  201. .end();
  202. }
  203. @Test
  204. public void testSimpleMapConfig()
  205. {
  206. Map<String, String> properties = new TreeMap<>();
  207. properties.put("map-a.a", "this is a");
  208. properties.put("map-a.b", "this is b");
  209. inspect(properties, null, null, null, binder -> bindConfig(binder).bind(LegacyMapConfigPresent.class))
  210. .component("ConfigurationFactoryTest$LegacyMapConfigPresent")
  211. .value("MapA[a]", "map-a.a", "-- n/a --", "this is a", "")
  212. .value("MapA[b]", "map-a.b", "-- n/a --", "this is b", "")
  213. .value("MapB", "map-b", "-- n/a --", "-- empty --", "")
  214. .end();
  215. }
  216. @Test
  217. public void testConfigMapValueConfig()
  218. {
  219. Map<String, String> properties = new TreeMap<>();
  220. properties.put("map-a.k1.string-value", "this is a");
  221. properties.put("map-a.k1.string-b", "this is b");
  222. properties.put("map-a.k2.string-value", "this is k2 a");
  223. properties.put("map-a.k2.string-b", "this is k2 b");
  224. inspect(properties, null, null, null, binder -> bindConfig(binder).bind(LegacyMapValueConfigPresent.class))
  225. .component("ConfigurationFactoryTest$LegacyMapValueConfigPresent")
  226. .value("MapA[k1]StringA", "map-a.k1.string-a", "defaultA", "this is a", "")
  227. .value("MapA[k1]StringB", "map-a.k1.string-b", "defaultB", "this is b", "")
  228. .value("MapA[k2]StringA", "map-a.k2.string-a", "defaultA", "this is k2 a", "")
  229. .value("MapA[k2]StringB", "map-a.k2.string-b", "defaultB", "this is k2 b", "")
  230. .end();
  231. }
  232. @Test
  233. public void testPrivateBinderConfig()
  234. {
  235. Map<String, String> properties = new TreeMap<>();
  236. properties.put("string-value", "some value");
  237. properties.put("boolean-value", "true");
  238. inspect(properties, null, null, null,
  239. binder -> {
  240. PrivateBinder privateBinder = binder.newPrivateBinder();
  241. bindConfig(privateBinder).bind(AnnotatedSetter.class);
  242. })
  243. .component("ConfigurationFactoryTest$AnnotatedSetter")
  244. .value("BooleanValue", "boolean-value", "false", "true", "")
  245. .value("StringValue", "string-value", "null", "some value", "")
  246. .end();
  247. }
  248. @Test
  249. public void testConfigAwareProviderConfig()
  250. {
  251. Map<String, String> properties = new TreeMap<>();
  252. properties.put("string-value", "some value");
  253. properties.put("boolean-value", "true");
  254. inspect(properties, null, null, null,
  255. binder -> binder.bind(Integer.class).toProvider(new ConfigurationAwareProvider<Integer>()
  256. {
  257. private ConfigurationFactory configurationFactory;
  258. @Override
  259. public void setConfigurationFactory(ConfigurationFactory configurationFactory)
  260. {
  261. this.configurationFactory = configurationFactory;
  262. }
  263. @Override
  264. public Integer get()
  265. {
  266. configurationFactory.build(AnnotatedSetter.class);
  267. return 3;
  268. }
  269. }))
  270. .component("")
  271. .value("BooleanValue", "boolean-value", "false", "true", "")
  272. .value("StringValue", "string-value", "null", "some value", "")
  273. .end();
  274. }
  275. private static class InspectionVerifier
  276. {
  277. private final Iterator<ConfigRecord<?>> recordIterator;
  278. private Iterator<ConfigAttribute> attributeIterator = null;
  279. public InspectionVerifier(SortedSet<ConfigRecord<?>> inspect)
  280. {
  281. recordIterator = inspect.iterator();
  282. }
  283. public InspectionVerifier component(String expectedName)
  284. {
  285. if (attributeIterator != null && attributeIterator.hasNext()) {
  286. fail("Extra attributes: " + Iterators.toString(attributeIterator));
  287. }
  288. ConfigRecord<?> record = recordIterator.next();
  289. assertEquals(record.getComponentName(), "".equals(expectedName) ? "" : (PACKAGE_NAME + expectedName));
  290. attributeIterator = record.getAttributes().iterator();
  291. return this;
  292. }
  293. public InspectionVerifier component(String annotation, String expectedName)
  294. {
  295. if (attributeIterator != null && attributeIterator.hasNext()) {
  296. fail("Extra attributes: " + Iterators.toString(attributeIterator));
  297. }
  298. ConfigRecord<?> record = recordIterator.next();
  299. assertEquals(record.getComponentName(), annotation + " " + PACKAGE_NAME + expectedName);
  300. attributeIterator = record.getAttributes().iterator();
  301. return this;
  302. }
  303. public InspectionVerifier value(String attributeName, String propertyName, String defaultValue, String currentValue, String description)
  304. {
  305. final ConfigAttribute attribute = attributeIterator.next();
  306. assertEquals(attribute.getAttributeName(), attributeName, "Attribute name");
  307. assertEquals(attribute.getPropertyName(), propertyName, "Property name");
  308. assertEquals(attribute.getDefaultValue(), defaultValue, "Default value");
  309. assertEquals(attribute.getCurrentValue(), currentValue, "Current value");
  310. assertEquals(attribute.getDescription(), description, "Description");
  311. return this;
  312. }
  313. public void end()
  314. {
  315. if (attributeIterator != null && attributeIterator.hasNext()) {
  316. fail("Extra attributes: " + Iterators.toString(attributeIterator));
  317. }
  318. if (recordIterator != null && recordIterator.hasNext()) {
  319. fail("Extra components: " + Iterators.toString(recordIterator));
  320. }
  321. }
  322. }
  323. @Retention(RetentionPolicy.RUNTIME)
  324. @Qualifier
  325. private @interface Prefixed
  326. {
  327. }
  328. }