protected void initializePropertySources() { if (environment.getPropertySources().contains(APOLLO_PROPERTY_SOURCE_NAME)) { //already initialized return; } CompositePropertySource composite = new CompositePropertySource(APOLLO_PROPERTY_SOURCE_NAME); //sort by order asc ImmutableSortedSet<Integer> orders = ImmutableSortedSet.copyOf(NAMESPACE_NAMES.keySet()); Iterator<Integer> iterator = orders.iterator(); while (iterator.hasNext()) { int order = iterator.next(); for (String namespace : NAMESPACE_NAMES.get(order)) { Config config = ConfigService.getConfig(namespace); composite.addPropertySource(new ConfigPropertySource(namespace, config)); } } environment.getPropertySources().addFirst(composite); }
/** * Add, remove or re-order any {@link PropertySource}s in this application's * environment. * @param environment this application's environment * @param args arguments passed to the {@code run} method * @see #configureEnvironment(ConfigurableEnvironment, String[]) */ protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) { MutablePropertySources sources = environment.getPropertySources(); if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { sources.addLast( new MapPropertySource("defaultProperties", this.defaultProperties)); } if (this.addCommandLineProperties && args.length > 0) { String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; if (sources.contains(name)) { PropertySource<?> source = sources.get(name); CompositePropertySource composite = new CompositePropertySource(name); composite.addPropertySource(new SimpleCommandLinePropertySource( name + "-" + args.hashCode(), args)); composite.addPropertySource(source); sources.replace(name, composite); } else { sources.addFirst(new SimpleCommandLinePropertySource(args)); } } }
/** * Finds all registered property sources of the given type. */ protected <S extends PropertySource<?>> List<S> findPropertySources(Class<S> sourceClass) { List<S> managedSources = new LinkedList<>(); LinkedList<PropertySource<?>> sources = toLinkedList(environment.getPropertySources()); while (!sources.isEmpty()) { PropertySource<?> source = sources.pop(); if (source instanceof CompositePropertySource) { CompositePropertySource comp = (CompositePropertySource) source; sources.addAll(comp.getPropertySources()); } else if (sourceClass.isInstance(source)) { managedSources.add(sourceClass.cast(source)); } } return managedSources; }
@Test public void shouldLocateLeaseAwareSources() { RequestedSecret rotating = RequestedSecret.rotating("secret/rotating"); DefaultSecretBackendConfigurer configurer = new DefaultSecretBackendConfigurer(); configurer.add(rotating); configurer.add("database/mysql/creds/readonly"); propertySourceLocator = new LeasingVaultPropertySourceLocator( new VaultProperties(), configurer, secretLeaseContainer); PropertySource<?> propertySource = propertySourceLocator .locate(configurableEnvironment); assertThat(propertySource).isInstanceOf(CompositePropertySource.class); verify(secretLeaseContainer).addRequestedSecret(rotating); verify(secretLeaseContainer).addRequestedSecret( RequestedSecret.renewable("database/mysql/creds/readonly")); }
@Test public void shouldLocatePropertySourcesInVaultApplicationContext() { VaultGenericBackendProperties backendProperties = new VaultGenericBackendProperties(); backendProperties.setApplicationName("wintermute"); propertySourceLocator = new VaultPropertySourceLocator(operations, new VaultProperties(), VaultPropertySourceLocatorSupport.createConfiguration(backendProperties)); when(configurableEnvironment.getActiveProfiles()) .thenReturn(new String[] { "vermillion", "periwinkle" }); PropertySource<?> propertySource = propertySourceLocator .locate(configurableEnvironment); assertThat(propertySource).isInstanceOf(CompositePropertySource.class); CompositePropertySource composite = (CompositePropertySource) propertySource; assertThat(composite.getPropertySources()).extracting("name").containsSequence( "secret/wintermute/periwinkle", "secret/wintermute/vermillion", "secret/wintermute"); }
@Test public void shouldLocatePropertySourcesInEachPathSpecifiedWhenApplicationNameContainsSeveral() { VaultGenericBackendProperties backendProperties = new VaultGenericBackendProperties(); backendProperties.setApplicationName("wintermute,straylight,icebreaker/armitage"); propertySourceLocator = new VaultPropertySourceLocator(operations, new VaultProperties(), VaultPropertySourceLocatorSupport.createConfiguration(backendProperties)); when(configurableEnvironment.getActiveProfiles()) .thenReturn(new String[] { "vermillion", "periwinkle" }); PropertySource<?> propertySource = propertySourceLocator .locate(configurableEnvironment); assertThat(propertySource).isInstanceOf(CompositePropertySource.class); CompositePropertySource composite = (CompositePropertySource) propertySource; assertThat(composite.getPropertySources()).extracting("name").contains( "secret/wintermute", "secret/straylight", "secret/icebreaker/armitage", "secret/wintermute/vermillion", "secret/wintermute/periwinkle", "secret/straylight/vermillion", "secret/straylight/periwinkle", "secret/icebreaker/armitage/vermillion", "secret/icebreaker/armitage/periwinkle"); }
@Test public void shouldCreatePropertySourcesInOrder() { DefaultSecretBackendConfigurer configurer = new DefaultSecretBackendConfigurer(); configurer.add(new MySecondSecretBackendMetadata()); configurer.add(new MyFirstSecretBackendMetadata()); propertySourceLocator = new VaultPropertySourceLocator(operations, new VaultProperties(), configurer); PropertySource<?> propertySource = propertySourceLocator .locate(configurableEnvironment); assertThat(propertySource).isInstanceOf(CompositePropertySource.class); CompositePropertySource composite = (CompositePropertySource) propertySource; assertThat(composite.getPropertySources()).extracting("name") .containsSequence("foo", "bar"); }
private PropertySource createPropertySource(AnnotationAttributes attributes, ConfigurableEnvironment environment, ResourceLoader resourceLoader, EncryptablePropertyResolver resolver, List<PropertySourceLoader> loaders) throws Exception { String name = generateName(attributes.getString("name")); String[] locations = attributes.getStringArray("value"); boolean ignoreResourceNotFound = attributes.getBoolean("ignoreResourceNotFound"); CompositePropertySource compositePropertySource = new CompositePropertySource(name); Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required"); for (String location : locations) { String resolvedLocation = environment.resolveRequiredPlaceholders(location); Resource resource = resourceLoader.getResource(resolvedLocation); if (!resource.exists()) { if (!ignoreResourceNotFound) { throw new IllegalStateException(String.format("Encryptable Property Source '%s' from location: %s Not Found", name, resolvedLocation)); } else { log.info("Ignoring NOT FOUND Encryptable Property Source '{}' from locations: {}", name, resolvedLocation); } } else { String actualName = name + "#" + resolvedLocation; loadPropertySource(loaders, resource, actualName) .ifPresent(compositePropertySource::addPropertySource); } } return new EncryptableEnumerablePropertySourceWrapper<>(compositePropertySource, resolver); }
@Test public void serviceUrlWithCompositePropertySource() { CompositePropertySource source = new CompositePropertySource("composite"); this.context.getEnvironment().getPropertySources().addFirst(source); source.addPropertySource(new MapPropertySource("config", Collections .<String, Object> singletonMap("eureka.client.serviceUrl.defaultZone", "http://example.com,http://example2.com"))); this.context.register(PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class); this.context.refresh(); assertEquals("{defaultZone=http://example.com,http://example2.com}", this.context.getBean(EurekaClientConfigBean.class).getServiceUrl() .toString()); assertEquals("[http://example.com/, http://example2.com/]", getEurekaServiceUrlsForDefaultZone()); }
@Override protected void doHealthCheck(Builder builder) throws Exception { PropertySource<?> propertySource = getPropertySource(); builder.up(); if (propertySource instanceof CompositePropertySource) { List<String> sources = new ArrayList<>(); for (PropertySource<?> ps : ((CompositePropertySource) propertySource).getPropertySources()) { sources.add(ps.getName()); } builder.withDetail("propertySources", sources); } else if (propertySource!=null) { builder.withDetail("propertySources", propertySource.toString()); } else { builder.unknown().withDetail("error", "no property sources located"); } }
@Test public void propertySourcesFound() throws Exception { String foo = this.environment.getProperty("foo"); assertThat("foo was wrong", foo, is(equalTo("bar-app-dev"))); String myBaz = this.environment.getProperty("my.baz"); assertThat("my.baz was wrong", myBaz, is(equalTo("bar-app-dev"))); MutablePropertySources propertySources = this.environment.getPropertySources(); PropertySource<?> bootstrapProperties = propertySources.get("bootstrapProperties"); assertThat("bootstrapProperties was null", bootstrapProperties, is(notNullValue())); assertThat("bootstrapProperties was wrong type", bootstrapProperties.getClass(), is(typeCompatibleWith(CompositePropertySource.class))); Collection<PropertySource<?>> consulSources = ((CompositePropertySource) bootstrapProperties).getPropertySources(); assertThat("consulSources was wrong size", consulSources, hasSize(1)); PropertySource<?> consulSource = consulSources.iterator().next(); assertThat("consulSource was wrong type", consulSource.getClass(), is(typeCompatibleWith(CompositePropertySource.class))); Collection<PropertySource<?>> fileSources = ((CompositePropertySource) consulSource).getPropertySources(); assertThat("fileSources was wrong size", fileSources, hasSize(4)); assertFileSourceNames(fileSources, APP_NAME_DEV_PROPS, APP_NAME_PROPS, APPLICATION_DEV_YML, APPLICATION_YML); }
@Override public PropertySource<?> locate(final Environment environment) { if (environment instanceof ConfigurableEnvironment) { final String sourceName = MongoDbPropertySource.class.getSimpleName(); final CompositePropertySource composite = new CompositePropertySource(sourceName); final MongoDbPropertySource source = new MongoDbPropertySource(sourceName, mongo); composite.addFirstPropertySource(source); return composite; } return null; }
private PropertySource<?> collatePropertySources(String name, List<ResourcePropertySource> propertySources) { if (propertySources.size() == 1) { return propertySources.get(0).withName(name); } CompositePropertySource result = new CompositePropertySource(name); for (int i = propertySources.size() - 1; i >= 0; i--) { result.addPropertySource(propertySources.get(i)); } return result; }
@SuppressWarnings("rawtypes") private static void processPropertySource(PropertySource propertySource, String prefix, Map<String, Object> result, boolean removePrefix) { if (propertySource instanceof MapPropertySource) { MapPropertySource mapPropertySource = (MapPropertySource) propertySource; processMap(mapPropertySource, prefix, result, removePrefix); } else if (propertySource instanceof CompositePropertySource) { CompositePropertySource compositePropertySource = (CompositePropertySource) propertySource; for (PropertySource sub : compositePropertySource.getPropertySources()) { processPropertySource(sub, prefix, result, removePrefix); } } }
private void addPropertySource(ResourcePropertySource propertySource) { String name = propertySource.getName(); MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources(); if (propertySources.contains(name) && this.propertySourceNames.contains(name)) { // We've already added a version, we need to extend it PropertySource<?> existing = propertySources.get(name); if (existing instanceof CompositePropertySource) { ((CompositePropertySource) existing).addFirstPropertySource(propertySource.withResourceName()); } else { if (existing instanceof ResourcePropertySource) { existing = ((ResourcePropertySource) existing).withResourceName(); } CompositePropertySource composite = new CompositePropertySource(name); composite.addPropertySource(propertySource.withResourceName()); composite.addPropertySource(existing); propertySources.replace(name, composite); } } else { if (this.propertySourceNames.isEmpty()) { propertySources.addLast(propertySource); } else { String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1); propertySources.addBefore(firstProcessed, propertySource); } } this.propertySourceNames.add(name); }
private void getPropertiesFromSource(PropertySource<?> propertySource, Map<String, Object> map) { if (propertySource instanceof MapPropertySource) { for (String key : ((MapPropertySource) propertySource).getPropertyNames()) { if (key.startsWith(DB_PREFIX)) { map.put(key.replaceFirst(DB_PREFIX, ""), propertySource.getProperty(key)); } } } if (propertySource instanceof CompositePropertySource) { for (PropertySource<?> s : ((CompositePropertySource) propertySource).getPropertySources()) { getPropertiesFromSource(s, map); } } }
private void processPropertySource(PropertySource<?> source, PropertySourcesPropertyResolver resolver) { if (source instanceof CompositePropertySource) { processCompositePropertySource((CompositePropertySource) source, resolver); } else if (source instanceof EnumerablePropertySource) { processEnumerablePropertySource((EnumerablePropertySource<?>) source, resolver, this.includes); } else { processNonEnumerablePropertySource(source, resolver); } }
@Test public void commandLinePropertySourceEnhancesEnvironment() throws Exception { SpringApplication application = new SpringApplication(ExampleConfig.class); application.setWebEnvironment(false); ConfigurableEnvironment environment = new StandardEnvironment(); environment.getPropertySources().addFirst(new MapPropertySource("commandLineArgs", Collections.<String, Object>singletonMap("foo", "original"))); application.setEnvironment(environment); this.context = application.run("--foo=bar", "--bar=foo"); assertThat(environment).has( matchingPropertySource(CompositePropertySource.class, "commandLineArgs")); assertThat(environment.getProperty("bar")).isEqualTo("foo"); // New command line properties take precedence assertThat(environment.getProperty("foo")).isEqualTo("bar"); }
@Test public void testCompositeValue() { PropertySource<?> map = this.propertySources.get("map"); CompositePropertySource composite = new CompositePropertySource("composite"); composite.addPropertySource(map); this.propertySources.replace("map", composite); PropertySourcesPropertyValues propertyValues = new PropertySourcesPropertyValues( this.propertySources); assertThat(propertyValues.getPropertyValue("foo").getValue()).isEqualTo("bar"); }
@Test public void testBindFromCompositePropertySource() throws Exception { this.targetName = "foo"; setupFactory(); MutablePropertySources sources = new MutablePropertySources(); CompositePropertySource composite = new CompositePropertySource("composite"); composite.addPropertySource(new MapPropertySource("map", Collections.singletonMap("foo.map.name", (Object) "blah"))); sources.addFirst(composite); this.factory.setPropertySources(sources); this.factory.afterPropertiesSet(); Foo foo = this.factory.getObject(); assertThat(foo.map.get("name")).isEqualTo("blah"); }
private void extract(String root, Map<String, PropertySource<?>> map, PropertySource<?> source) { if (source instanceof CompositePropertySource) { for (PropertySource<?> nest : ((CompositePropertySource) source) .getPropertySources()) { extract(source.getName() + ":", map, nest); } } else { map.put(root + source.getName(), source); } }
@SuppressWarnings("unchecked") @Test public void testCompositeSource() throws Exception { EnvironmentEndpoint report = getEndpointBean(); CompositePropertySource source = new CompositePropertySource("composite"); source.addPropertySource(new MapPropertySource("one", Collections.singletonMap("foo", (Object) "bar"))); source.addPropertySource(new MapPropertySource("two", Collections.singletonMap("foo", (Object) "spam"))); this.context.getEnvironment().getPropertySources().addFirst(source); Map<String, Object> env = report.invoke(); assertThat(((Map<String, Object>) env.get("composite:one")).get("foo")) .isEqualTo("bar"); }
/** * Initialize nested {@link PropertySource}s inside the * {@link CompositePropertySource}. * @param propertySource the {@link CompositePropertySource} to initialize. */ protected void initialize(CompositePropertySource propertySource) { for (PropertySource<?> source : propertySource.getPropertySources()) { ((VaultPropertySource) source).init(); } }
@Override public PropertySource<?> locate(Environment environment) { if (propertySourceLocatorConfiguration instanceof EnvironmentAware) { ((EnvironmentAware) propertySourceLocatorConfiguration) .setEnvironment(environment); } CompositePropertySource propertySource = createCompositePropertySource( environment); initialize(propertySource); return propertySource; }
/** * Creates a {@link CompositePropertySource}. * * @param environment must not be {@literal null}. * @return */ protected CompositePropertySource createCompositePropertySource( Environment environment) { List<PropertySource<?>> propertySources = doCreatePropertySources(environment); return doCreateCompositePropertySource(propertySourceName, propertySources); }
/** * Create a {@link CompositePropertySource} given a {@link List} of * {@link PropertySource}s. * * @param propertySourceName the property source name. * @param propertySources the property sources. * @return the {@link CompositePropertySource} to use. */ protected CompositePropertySource doCreateCompositePropertySource( String propertySourceName, List<PropertySource<?>> propertySources) { CompositePropertySource compositePropertySource = new CompositePropertySource( propertySourceName); for (PropertySource<?> propertySource : propertySources) { compositePropertySource.addPropertySource(propertySource); } return compositePropertySource; }
@Test public void shouldLocatePropertySources() { when(configurableEnvironment.getActiveProfiles()).thenReturn(new String[0]); PropertySource<?> propertySource = propertySourceLocator .locate(configurableEnvironment); assertThat(propertySource).isInstanceOf(CompositePropertySource.class); CompositePropertySource composite = (CompositePropertySource) propertySource; assertThat(composite.getPropertySources()).hasSize(1); verify(secretLeaseContainer) .addRequestedSecret(RequestedSecret.rotating("secret/application")); }
@Test public void shouldLocatePropertySourcesForActiveProfilesInDefaultContext() { when(configurableEnvironment.getActiveProfiles()) .thenReturn(new String[] { "vermillion", "periwinkle" }); PropertySource<?> propertySource = propertySourceLocator .locate(configurableEnvironment); assertThat(propertySource).isInstanceOf(CompositePropertySource.class); CompositePropertySource composite = (CompositePropertySource) propertySource; assertThat(composite.getPropertySources()).extracting("name").containsSequence( "secret/application/periwinkle", "secret/application/vermillion"); }
private void addPropertySource(PropertySource<?> propertySource) { String name = propertySource.getName(); MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources(); if (propertySources.contains(name) && this.propertySourceNames.contains(name)) { // We've already added a version, we need to extend it PropertySource<?> existing = propertySources.get(name); PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ? ((ResourcePropertySource) propertySource).withResourceName() : propertySource); if (existing instanceof CompositePropertySource) { ((CompositePropertySource) existing).addFirstPropertySource(newSource); } else { if (existing instanceof ResourcePropertySource) { existing = ((ResourcePropertySource) existing).withResourceName(); } CompositePropertySource composite = new CompositePropertySource(name); composite.addPropertySource(newSource); composite.addPropertySource(existing); propertySources.replace(name, composite); } } else { if (this.propertySourceNames.isEmpty()) { propertySources.addLast(propertySource); } else { String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1); propertySources.addBefore(firstProcessed, propertySource); } } this.propertySourceNames.add(name); }
/** * Process the given <code>@PropertySource</code> annotation metadata. * @param propertySource metadata for the <code>@PropertySource</code> annotation found * @throws IOException if loading a property source failed */ private void processPropertySource(AnnotationAttributes propertySource) throws IOException { String name = propertySource.getString("name"); String[] locations = propertySource.getStringArray("value"); int locationCount = locations.length; if (locationCount == 0) { throw new IllegalArgumentException("At least one @PropertySource(value) location is required"); } for (int i = 0; i < locationCount; i++) { locations[i] = this.environment.resolveRequiredPlaceholders(locations[i]); } ClassLoader classLoader = this.resourceLoader.getClassLoader(); if (!StringUtils.hasText(name)) { for (String location : locations) { this.propertySources.push(new ResourcePropertySource(location, classLoader)); } } else { if (locationCount == 1) { this.propertySources.push(new ResourcePropertySource(name, locations[0], classLoader)); } else { CompositePropertySource ps = new CompositePropertySource(name); for (int i = locations.length - 1; i >= 0; i--) { ps.addPropertySource(new ResourcePropertySource(locations[i], classLoader)); } this.propertySources.push(ps); } } }