diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CassandraCnbBindingProcessor.java b/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CassandraCnbBindingProcessor.java deleted file mode 100644 index 24b20b1..0000000 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CassandraCnbBindingProcessor.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - -import org.springframework.cloud.cnb.Binding; - -import java.util.Map; - - -public class CassandraCnbBindingProcessor implements CnbBindingProcessor { - public static final String CASSANDRA_KIND = "cassandra"; - - @Override - public boolean accept(Binding binding) { - return binding.getKind().equals(CASSANDRA_KIND); - } - - @Override - public void process(Binding binding, Map properties) { - properties.put("spring.data.cassandra.username", binding.getSecret().get("username")); - properties.put("spring.data.cassandra.password", binding.getSecret().get("password")); - properties.put("spring.data.cassandra.contact-points", binding.getSecret().get("node_ips")); - properties.put("spring.data.cassandra.port", binding.getSecret().get("port")); - } - - @Override - public CnbBindingProcessorProperties getProperties() { - return null; - } -} diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingProcessor.java b/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingProcessor.java deleted file mode 100644 index 1c4f23e..0000000 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingProcessor.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - -import java.util.Map; - -import org.springframework.cloud.cnb.Binding; - -public interface CnbBindingProcessor { - - boolean accept(Binding binding); - - void process(Binding binding, Map properties); - - CnbBindingProcessorProperties getProperties(); -} diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingProcessorProperties.java b/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingProcessorProperties.java deleted file mode 100644 index b57792d..0000000 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingProcessorProperties.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - -/** - * Properties describing a CfEnvProcessor, mainly used for better logging messages in {@link CnbBindingProcessor}. - * - * @author Mark Pollack - */ -public class CnbBindingProcessorProperties { - - private String propertyPrefixes; - - private String serviceName; - - private CnbBindingProcessorProperties() { - } - - public static Builder builder() { - return new CnbBindingProcessorProperties.Builder(); - } - - /** - * A string containing the values of property prefixes that will be set in the {@code process} method. Used - * for logging purposes. - * @return property prefix values set in the {@code process} method - */ - public String getPropertyPrefixes() { - return propertyPrefixes; - } - - /** - * A name that describes the service being processed, eg. 'Redis', 'MongoDB'. Used for logging purposes. - * @return name that describes the service being processed - */ - public String getServiceName() { - return serviceName; - } - - - public static class Builder { - private CnbBindingProcessorProperties processorProperties = new CnbBindingProcessorProperties(); - - // Todo: add kind & provider, make serviceName the binding name - - public Builder propertyPrefixes(String propertyPrefixes) { - this.processorProperties.propertyPrefixes = propertyPrefixes; - return this; - } - - public Builder serviceName(String serviceName) { - this.processorProperties.serviceName = serviceName; - return this; - } - - public CnbBindingProcessorProperties build() { - return processorProperties; - } - } -} diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingsPostProcessor.java b/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingsPostProcessor.java deleted file mode 100644 index 585032c..0000000 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/CnbBindingsPostProcessor.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.config.ConfigFileApplicationListener; -import org.springframework.boot.context.event.ApplicationPreparedEvent; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.cloud.cnb.core.CNBBindingsSingleton; -import org.springframework.cloud.cnb.Binding; -import org.springframework.cloud.cnb.Bindings; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.CommandLinePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.stereotype.Component; - -/** - * An EnvironmentPostProcessor that iterates over {@link CnbBindingProcessor} implementations to contribute - * Spring Boot properties for bound Cloud Foundry Services. - * - * Implementation of {@link CnbBindingProcessor }should be registered using the - * {@code resources/META-INF/spring.factories} property file. - * - * @author Mark Pollack - * @author David Turanski - */ -@Component -public class CnbBindingsPostProcessor implements EnvironmentPostProcessor, Ordered, ApplicationListener { - - private static DeferredLog DEFERRED_LOG = new DeferredLog(); - - private static int invocationCount; - - // Before ConfigFileApplicationListener so values there can use these ones - private int order = ConfigFileApplicationListener.DEFAULT_ORDER - 1; - - public CnbBindingsPostProcessor() { - } - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, - SpringApplication application) { - - // TODO: allow users to disable processing of a given binding by name, kind, or processor - - increaseInvocationCount(); - Bindings bindings = CNBBindingsSingleton.getCnbBindingsInstance(); - - if (bindings.hasBindings()) { - List allBindings = bindings.findAllBindings(); - - List cnbBindingProcessors = SpringFactoriesLoader - .loadFactories(CnbBindingProcessor.class, getClass().getClassLoader()); - AnnotationAwareOrderComparator.sort(cnbBindingProcessors); - - for (CnbBindingProcessor processor : cnbBindingProcessors) { - List cnbBindings = allBindings.stream() - .filter(processor::accept) - .collect(Collectors.toList()); - - - if (cnbBindings.size() == 1) { - Binding binding = cnbBindings.get(0); - Map properties = new LinkedHashMap<>(); - - processor.process(binding, properties); - - MutablePropertySources propertySources = environment.getPropertySources(); - - if (propertySources.contains( - CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME)) { - propertySources.addAfter( - CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME, - new MapPropertySource(processor.getClass().getSimpleName(), properties)); - } else { - propertySources.addFirst( - new MapPropertySource(processor.getClass().getSimpleName(), properties)); - } - - if (invocationCount == 1) { - DEFERRED_LOG.info( - "Setting " + processor.getProperties().getPropertyPrefixes() + - " properties from bound service [" - + binding.getName() + "] using " + processor.getClass().getName()); - } - } - } - } else { - if (invocationCount == 1) { - DEFERRED_LOG.debug( - "Not setting properties, CNB Bindings not detected"); - } - } - } - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof ApplicationPreparedEvent) { - DEFERRED_LOG - .switchTo(CnbBindingsPostProcessor.class); - } - } - - /** - * EnvironmentPostProcessors can end up getting called twice due to spring-cloud-commons - * functionality - */ - protected void increaseInvocationCount() { - synchronized (this) { - invocationCount++; - } - } - -} diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/ConnectorLibraryDetector.java b/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/ConnectorLibraryDetector.java deleted file mode 100644 index 4a8a162..0000000 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/ConnectorLibraryDetector.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.cnb.boot; - -import org.springframework.util.ClassUtils; - -/** - * Determine if the Connector Library is on the classpath - * @author Mark Pollack - */ -public abstract class ConnectorLibraryDetector { - - public static String MESSAGE = "Exiting the application since the Spring Cloud Connector library has been detected on the classpath. Please remove this dependency from your project and set the environment variable JBP_CONFIG_SPRING_AUTO_RECONFIGURATION '{enabled: false}' in the Cloud Foundry manifest."; - - private static boolean usingConnectorLibrary; - - static { - ClassLoader classLoader = ConnectorLibraryDetector.class.getClassLoader(); - usingConnectorLibrary = ClassUtils.isPresent("org.springframework.cloud.Cloud", classLoader) || - ClassUtils.isPresent("org.cloudfoundry.reconfiguration.org.springframework.cloud.Cloud", classLoader); - } - - static boolean isUsingConnectorLibrary() { - return usingConnectorLibrary; - } - - static void assertNoConnectorLibrary() { - if (ConnectorLibraryDetector.isUsingConnectorLibrary()) { - throw new IllegalStateException(ConnectorLibraryDetector.MESSAGE); - } - } -} diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/DeferredLog.java b/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/DeferredLog.java deleted file mode 100644 index 7c8c395..0000000 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/DeferredLog.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2012-2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.cnb.boot; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Deferred {@link Log} that can be used to store messages that shouldn't be written until - * the logging system is fully initialized. - * - * @author Phillip Webb - * @since 1.3.0 - */ -public class DeferredLog implements Log { - - private volatile Log destination; - - private final List lines = new ArrayList<>(); - - @Override - public boolean isTraceEnabled() { - synchronized (this.lines) { - return (this.destination != null) ? this.destination.isTraceEnabled() : true; - } - } - - @Override - public boolean isDebugEnabled() { - synchronized (this.lines) { - return (this.destination != null) ? this.destination.isDebugEnabled() : true; - } - } - - @Override - public boolean isInfoEnabled() { - synchronized (this.lines) { - return (this.destination != null) ? this.destination.isInfoEnabled() : true; - } - } - - @Override - public boolean isWarnEnabled() { - synchronized (this.lines) { - return (this.destination != null) ? this.destination.isWarnEnabled() : true; - } - } - - @Override - public boolean isErrorEnabled() { - synchronized (this.lines) { - return (this.destination != null) ? this.destination.isErrorEnabled() : true; - } - } - - @Override - public boolean isFatalEnabled() { - synchronized (this.lines) { - return (this.destination != null) ? this.destination.isFatalEnabled() : true; - } - } - - @Override - public void trace(Object message) { - log(LogLevel.TRACE, message, null); - } - - @Override - public void trace(Object message, Throwable t) { - log(LogLevel.TRACE, message, t); - } - - @Override - public void debug(Object message) { - log(LogLevel.DEBUG, message, null); - } - - @Override - public void debug(Object message, Throwable t) { - log(LogLevel.DEBUG, message, t); - } - - @Override - public void info(Object message) { - log(LogLevel.INFO, message, null); - } - - @Override - public void info(Object message, Throwable t) { - log(LogLevel.INFO, message, t); - } - - @Override - public void warn(Object message) { - log(LogLevel.WARN, message, null); - } - - @Override - public void warn(Object message, Throwable t) { - log(LogLevel.WARN, message, t); - } - - @Override - public void error(Object message) { - log(LogLevel.ERROR, message, null); - } - - @Override - public void error(Object message, Throwable t) { - log(LogLevel.ERROR, message, t); - } - - @Override - public void fatal(Object message) { - log(LogLevel.FATAL, message, null); - } - - @Override - public void fatal(Object message, Throwable t) { - log(LogLevel.FATAL, message, t); - } - - private void log(LogLevel level, Object message, Throwable t) { - synchronized (this.lines) { - if (this.destination != null) { - logTo(this.destination, level, message, t); - } - else { - this.lines.add(new Line(level, message, t)); - } - } - } - - /** - * Switch from deferred logging to immediate logging to the specified destination. - * @param destination the new log destination - * @since 2.1.0 - */ - public void switchTo(Class destination) { - switchTo(LogFactory.getLog(destination)); - } - - /** - * Switch from deferred logging to immediate logging to the specified destination. - * @param destination the new log destination - * @since 2.1.0 - */ - public void switchTo(Log destination) { - synchronized (this.lines) { - replayTo(destination); - this.destination = destination; - } - } - - /** - * Replay deferred logging to the specified destination. - * @param destination the destination for the deferred log messages - */ - public void replayTo(Class destination) { - replayTo(LogFactory.getLog(destination)); - } - - /** - * Replay deferred logging to the specified destination. - * @param destination the destination for the deferred log messages - */ - public void replayTo(Log destination) { - synchronized (this.lines) { - for (Line line : this.lines) { - logTo(destination, line.getLevel(), line.getMessage(), - line.getThrowable()); - } - this.lines.clear(); - } - } - - /** - * Replay from a source log to a destination log when the source is deferred. - * @param source the source logger - * @param destination the destination logger class - * @return the destination - */ - public static Log replay(Log source, Class destination) { - return replay(source, LogFactory.getLog(destination)); - } - - /** - * Replay from a source log to a destination log when the source is deferred. - * @param source the source logger - * @param destination the destination logger - * @return the destination - */ - public static Log replay(Log source, Log destination) { - if (source instanceof DeferredLog) { - ((DeferredLog) source).replayTo(destination); - } - return destination; - } - - private static void logTo(Log log, LogLevel level, Object message, - Throwable throwable) { - switch (level) { - case TRACE: - log.trace(message, throwable); - return; - case DEBUG: - log.debug(message, throwable); - return; - case INFO: - log.info(message, throwable); - return; - case WARN: - log.warn(message, throwable); - return; - case ERROR: - log.error(message, throwable); - return; - case FATAL: - log.fatal(message, throwable); - return; - } - } - - private static class Line { - - private final LogLevel level; - - private final Object message; - - private final Throwable throwable; - - Line(LogLevel level, Object message, Throwable throwable) { - this.level = level; - this.message = message; - this.throwable = throwable; - } - - public LogLevel getLevel() { - return this.level; - } - - public Object getMessage() { - return this.message; - } - - public Throwable getThrowable() { - return this.throwable; - } - - } - -} diff --git a/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/CassandraCnbBindingProcessorTests.java b/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/CassandraCnbBindingProcessorTests.java deleted file mode 100644 index 11cdc58..0000000 --- a/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/CassandraCnbBindingProcessorTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -import org.springframework.cloud.cnb.Binding; - - -import static org.assertj.core.api.Assertions.assertThat; - -public class CassandraCnbBindingProcessorTests { - - @Test - public void acceptIfCassandraKind() { - CassandraCnbBindingProcessor bindingProcessor = new CassandraCnbBindingProcessor(); - Map bindingMetadata = new HashMap(); - bindingMetadata.put("kind", "cassandra"); - Binding binding = new Binding(bindingMetadata, new HashMap()); - assertThat(bindingProcessor.accept(binding)).isTrue(); - } - - @Test - public void rejectIfNotCassandraKind() { - CassandraCnbBindingProcessor bindingProcessor = new CassandraCnbBindingProcessor(); - Map bindingMetadata = new HashMap(); - bindingMetadata.put("kind", "mysql"); - Binding binding = new Binding(bindingMetadata, new HashMap()); - assertThat(bindingProcessor.accept(binding)).isFalse(); - } - - @Test - public void processDataSourcePropertiesTest() { - CassandraCnbBindingProcessor bindingProcessor = new CassandraCnbBindingProcessor(); - Map bindingMetadata = new HashMap(); - bindingMetadata.put("kind", "cassandra"); - Map bindingSecret = new HashMap(); - bindingSecret.put("port", "9042"); - bindingSecret.put("node_ips", "10.0.4.35,10.0.4.36"); - bindingSecret.put("password", "some-password"); - bindingSecret.put("username", "some-username"); - Binding binding = new Binding(bindingMetadata, bindingSecret); - Map properties = new HashMap(); - bindingProcessor.process(binding, properties); - assertThat(properties.get("spring.data.cassandra.username")).isEqualTo("some-username"); - assertThat(properties.get("spring.data.cassandra.password")).isEqualTo("some-password"); - assertThat(properties.get("spring.data.cassandra.contact-points")).isEqualTo("10.0.4.35,10.0.4.36"); - assertThat(properties.get("spring.data.cassandra.port")).isEqualTo("9042"); - } - -} diff --git a/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/CnbBindingsPostProcessorTest.java b/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/CnbBindingsPostProcessorTest.java deleted file mode 100644 index 4bc234a..0000000 --- a/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/CnbBindingsPostProcessorTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; - -import org.junit.Test; - -import org.springframework.boot.Banner; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.cnb.boot.test.EnvMock; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.util.CollectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -public class CnbBindingsPostProcessorTest { - - @Test - public void testPostProcessEnvironment(){ - Path resourceDirectory = Paths.get("src", "test", "resources", "test-bindings"); - String bindingsDir = resourceDirectory.toFile().getAbsolutePath(); - - new EnvMock(bindingsDir); - - CnbBindingsPostProcessor environmentPostProcessor = new CnbBindingsPostProcessor(); - - environmentPostProcessor.postProcessEnvironment(getEnvironment(), - null); - assertThat(getEnvironment().getProperty("spring.datasource.url")) - .isEqualTo("jdbc:mysql://10.0.4.35:3306/mysql_name?user=mysql_username&password=mysql_password"); - assertThat( - getEnvironment().getProperty("spring.datasource.username")) - .isEqualTo("mysql_username"); - assertThat( - getEnvironment().getProperty("spring.datasource.password")) - .isEqualTo("mysql_password"); - } - - // TODO: test multiple services - - @Test - public void testNoBindingsPresent(){ - CnbBindingsPostProcessor environmentPostProcessor = new CnbBindingsPostProcessor(); - - // doen't fail - environmentPostProcessor.postProcessEnvironment(getEnvironment(), - null); - } - - public ConfigurableEnvironment getEnvironment() { - return getEnvironment(null); - } - - public ConfigurableEnvironment getEnvironment(Map properties) { - SpringApplicationBuilder builder = new SpringApplicationBuilder(TestApp.class) - .web(WebApplicationType.NONE); - if (!CollectionUtils.isEmpty(properties)) { - builder.properties(properties); - } - builder.bannerMode(Banner.Mode.OFF); - ConfigurableApplicationContext applicationContext = builder.run(); - ConfigurableEnvironment environment = applicationContext.getEnvironment(); - applicationContext.close(); - return environment; - } - - @SpringBootApplication - static class TestApp { - } - -} diff --git a/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/DeferredLogTests.java b/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/DeferredLogTests.java deleted file mode 100644 index c8a89b7..0000000 --- a/cnb-bindings-boot/src/test/java/org/springframework/cloud/cnb/boot/DeferredLogTests.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.cloud.cnb.boot; - - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.junit.Test; - -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -/** - * Tests for {@link DeferredLog}. - * - * @author Phillip Webb - */ -public class DeferredLogTests { - - private DeferredLog deferredLog = new DeferredLog(); - - private Object message = "Message"; - - private Throwable throwable = new IllegalStateException(); - - private Log log = mock(Log.class); - - @Test - public void isTraceEnabled() { - assertThat(this.deferredLog.isTraceEnabled()).isTrue(); - } - - @Test - public void isDebugEnabled() { - assertThat(this.deferredLog.isDebugEnabled()).isTrue(); - } - - @Test - public void isInfoEnabled() { - assertThat(this.deferredLog.isInfoEnabled()).isTrue(); - } - - @Test - public void isWarnEnabled() { - assertThat(this.deferredLog.isWarnEnabled()).isTrue(); - } - - @Test - public void isErrorEnabled() { - assertThat(this.deferredLog.isErrorEnabled()).isTrue(); - } - - @Test - public void isFatalEnabled() { - assertThat(this.deferredLog.isFatalEnabled()).isTrue(); - } - - @Test - public void trace() { - this.deferredLog.trace(this.message); - this.deferredLog.replayTo(this.log); - verify(this.log).trace(this.message, null); - } - - @Test - public void traceWithThrowable() { - this.deferredLog.trace(this.message, this.throwable); - this.deferredLog.replayTo(this.log); - verify(this.log).trace(this.message, this.throwable); - } - - @Test - public void debug() { - this.deferredLog.debug(this.message); - this.deferredLog.replayTo(this.log); - verify(this.log).debug(this.message, null); - } - - @Test - public void debugWithThrowable() { - this.deferredLog.debug(this.message, this.throwable); - this.deferredLog.replayTo(this.log); - verify(this.log).debug(this.message, this.throwable); - } - - @Test - public void info() { - this.deferredLog.info(this.message); - this.deferredLog.replayTo(this.log); - verify(this.log).info(this.message, null); - } - - @Test - public void infoWithThrowable() { - this.deferredLog.info(this.message, this.throwable); - this.deferredLog.replayTo(this.log); - verify(this.log).info(this.message, this.throwable); - } - - @Test - public void warn() { - this.deferredLog.warn(this.message); - this.deferredLog.replayTo(this.log); - verify(this.log).warn(this.message, null); - } - - @Test - public void warnWithThrowable() { - this.deferredLog.warn(this.message, this.throwable); - this.deferredLog.replayTo(this.log); - verify(this.log).warn(this.message, this.throwable); - } - - @Test - public void error() { - this.deferredLog.error(this.message); - this.deferredLog.replayTo(this.log); - verify(this.log).error(this.message, null); - } - - @Test - public void errorWithThrowable() { - this.deferredLog.error(this.message, this.throwable); - this.deferredLog.replayTo(this.log); - verify(this.log).error(this.message, this.throwable); - } - - @Test - public void fatal() { - this.deferredLog.fatal(this.message); - this.deferredLog.replayTo(this.log); - verify(this.log).fatal(this.message, null); - } - - @Test - public void fatalWithThrowable() { - this.deferredLog.fatal(this.message, this.throwable); - this.deferredLog.replayTo(this.log); - verify(this.log).fatal(this.message, this.throwable); - } - - @Test - public void clearsOnReplayTo() { - this.deferredLog.info("1"); - this.deferredLog.fatal("2"); - Log log2 = mock(Log.class); - this.deferredLog.replayTo(this.log); - this.deferredLog.replayTo(log2); - verify(this.log).info("1", null); - verify(this.log).fatal("2", null); - verifyNoMoreInteractions(this.log); - verifyNoInteractions(log2); - } - - @SuppressWarnings("unchecked") - @Test - public void switchTo() { - List lines = (List) ReflectionTestUtils.getField(this.deferredLog, - "lines"); - assertThat(lines).isEmpty(); - - this.deferredLog.error(this.message, this.throwable); - assertThat(lines).hasSize(1); - - this.deferredLog.switchTo(this.log); - assertThat(lines).isEmpty(); - - this.deferredLog.info("Message2"); - assertThat(lines).isEmpty(); - - verify(this.log).error(this.message, this.throwable); - verify(this.log).info("Message2", null); - } -} - diff --git a/cnb-bindings/src/main/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessor.java b/cnb-bindings/src/main/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessor.java index c7e0189..5497405 100644 --- a/cnb-bindings/src/main/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessor.java +++ b/cnb-bindings/src/main/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessor.java @@ -50,12 +50,12 @@ public final class BindingsEnvironmentPostProcessor implements EnvironmentPostPr */ public static final String BINDINGS_PROPERTY_SOURCE_NAME = "cnbBindings"; + final List processors; + private final Log log = LogFactory.getLog(getClass()); private final Bindings bindings; - private final List processors; - /** * Creates a new instance of {@code BindingsEnvironmentPostProcessor} using the {@link Bindings} available in the * environment and the {@link BindingsPropertiesProcessor}s registered with {@link SpringFactoriesLoader}. diff --git a/cnb-bindings/src/main/java/org/springframework/cloud/bindings/CassandraBindingsPropertiesProcessor.java b/cnb-bindings/src/main/java/org/springframework/cloud/bindings/CassandraBindingsPropertiesProcessor.java new file mode 100644 index 0000000..ed19690 --- /dev/null +++ b/cnb-bindings/src/main/java/org/springframework/cloud/bindings/CassandraBindingsPropertiesProcessor.java @@ -0,0 +1,46 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.bindings; + +import org.jetbrains.annotations.NotNull; +import org.springframework.lang.NonNull; + +import java.util.Map; + +/** + * An implementation of {@link BindingsPropertiesProcessor} that detects {@link Binding}s of kind: {@value KIND}. + */ +public final class CassandraBindingsPropertiesProcessor implements BindingsPropertiesProcessor { + + /** + * The {@link Binding} kind that this processor is interested in: {@value}. + **/ + public static final String KIND = "cassandra"; + + @Override + public void process(@NonNull Bindings bindings, @NotNull Map properties) { + bindings.filterBindings(KIND).forEach(binding -> { + Map secret = binding.getSecret(); + + properties.put("spring.data.cassandra.contact-points", secret.get("node_ips")); + properties.put("spring.data.cassandra.password", secret.get("password")); + properties.put("spring.data.cassandra.port", secret.get("port")); + properties.put("spring.data.cassandra.username", secret.get("username")); + }); + } + +} diff --git a/cnb-bindings/src/main/resources/META-INF/spring.factories b/cnb-bindings/src/main/resources/META-INF/spring.factories index f368657..d06d7a4 100644 --- a/cnb-bindings/src/main/resources/META-INF/spring.factories +++ b/cnb-bindings/src/main/resources/META-INF/spring.factories @@ -1,2 +1,5 @@ org.springframework.boot.env.EnvironmentPostProcessor=\ org.springframework.cloud.bindings.BindingsEnvironmentPostProcessor +# Included implementations +org.springframework.cloud.bindings.BindingsPropertiesProcessor=\ + org.springframework.cloud.bindings.CassandraBindingsPropertiesProcessor diff --git a/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessorTest.java b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessorTest.java index d037065..fa84261 100644 --- a/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessorTest.java +++ b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsEnvironmentPostProcessorTest.java @@ -113,4 +113,11 @@ final class BindingsEnvironmentPostProcessorTest { assertThat(new BindingsEnvironmentPostProcessor(new Bindings()).getOrder()) .isLessThan(ConfigFileApplicationListener.DEFAULT_ORDER); } + + @Test + @DisplayName("included implementations are registered") + void includedImplementations() { + assertThat(new BindingsEnvironmentPostProcessor().processors).hasSize(1); + } + } diff --git a/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsTests.java b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsTests.java index e3ed083..ce8d6f1 100644 --- a/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsTests.java +++ b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/BindingsTests.java @@ -23,8 +23,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -78,18 +76,13 @@ final class BindingsTests { private final Bindings bindings = new Bindings( new Binding("test-name-1", Paths.get("src/test/resources/test-name-1"), - metadata("test-kind-1", "test-provider-1"), Collections.emptyMap()), + new FluentMap().withEntry("kind", "test-kind-1").withEntry("provider", "test-provider-1"), + Collections.emptyMap()), new Binding("test-name-2", Paths.get("src/test/resources/test-name-2"), - metadata("test-kind-2", "test-provider-2"), Collections.emptyMap()) + new FluentMap().withEntry("kind", "test-kind-2").withEntry("provider", "test-provider-2"), + Collections.emptyMap()) ); - private Map metadata(String kind, String provider) { - Map metadata = new HashMap<>(2); - metadata.put("kind", kind); - metadata.put("provider", provider); - return metadata; - } - @Test @DisplayName("returns content") void getBindings() { diff --git a/cnb-bindings/src/test/java/org/springframework/cloud/bindings/CassandraBindingsPropertiesProcessorTest.java b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/CassandraBindingsPropertiesProcessorTest.java new file mode 100644 index 0000000..aeca6bd --- /dev/null +++ b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/CassandraBindingsPropertiesProcessorTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.bindings; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashMap; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.cloud.bindings.CassandraBindingsPropertiesProcessor.KIND; + +@DisplayName("Cassandra BindingsPropertiesProcessor") +final class CassandraBindingsPropertiesProcessorTest { + + @Test + @DisplayName("contributes properties") + void test() { + HashMap properties = new HashMap<>(); + + new CassandraBindingsPropertiesProcessor().process(new Bindings( + new Binding("test-name", Paths.get("test-path"), + Collections.singletonMap("kind", KIND), + new FluentMap() + .withEntry("node_ips", "test-node-ips") + .withEntry("password", "test-password") + .withEntry("port", "test-port") + .withEntry("username", "test-username") + ) + ), properties); + + assertThat(properties) + .containsEntry("spring.data.cassandra.contact-points", "test-node-ips") + .containsEntry("spring.data.cassandra.password", "test-password") + .containsEntry("spring.data.cassandra.port", "test-port") + .containsEntry("spring.data.cassandra.username", "test-username"); + } + +} diff --git a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/LogLevel.java b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/FluentMap.java similarity index 66% rename from cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/LogLevel.java rename to cnb-bindings/src/test/java/org/springframework/cloud/bindings/FluentMap.java index cc1f95b..60b08fd 100644 --- a/cnb-bindings-boot/src/main/java/org/springframework/cloud/cnb/boot/LogLevel.java +++ b/cnb-bindings/src/test/java/org/springframework/cloud/bindings/FluentMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,15 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.cnb.boot; -/** - * Logging levels supported by a LoggingSystem. - * - * @author Phillip Webb - */ -public enum LogLevel { +package org.springframework.cloud.bindings; - TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF +import java.util.HashMap; + +final class FluentMap extends HashMap { + + FluentMap withEntry(String key, String value) { + put(key, value); + return this; + } }