Single Project

And now we arrive at the end, a single concise project.

Signed-off-by: Ben Hale <bhale@vmware.com>
This commit is contained in:
Ben Hale
2020-05-09 09:03:58 -07:00
parent 04eed55e6a
commit ff878c8c95
60 changed files with 328 additions and 868 deletions

View File

@@ -1,15 +0,0 @@
^\Q/*\E$
^\Q * Copyright \E(20\d\d\-)?20\d\d\Q the original author or authors.\E$
^\Q *\E$
^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$
^\Q * you may not use this file except in compliance with the License.\E$
^\Q * You may obtain a copy of the License at\E$
^\Q *\E$
^\Q * http://www.apache.org/licenses/LICENSE-2.0\E$
^\Q *\E$
^\Q * Unless required by applicable law or agreed to in writing, software\E$
^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$
^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$
^\Q * See the License for the specific language governing permissions and\E$
^\Q * limitations under the License.\E$
^\Q */\E$

View File

@@ -1,185 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<!-- Root Checks -->
<module name="RegexpHeader">
<property name="headerFile" value="src/checkstyle/checkstyle-header.txt"/>
<property name="fileExtensions" value="java"/>
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="TreeWalker">
<property name="tabWidth" value="4"/>
<!--<module name="LineLength">-->
<!--<property name="max" value="120"/>-->
<!--</module>-->
<!-- Annotations -->
<module name="AnnotationUseStyle">
<property name="elementStyle" value="compact"/>
<property name="trailingArrayComma" value="never"/>
<property name="closingParens" value="never"/>
</module>
<module name="MissingOverride"/>
<module name="PackageAnnotation"/>
<module name="AnnotationLocation">
<property name="allowSamelineSingleParameterlessAnnotation"
value="false"/>
</module>
<!-- Block Checks -->
<module name="EmptyBlock">
<property name="option" value="text"/>
</module>
<!--
<module name="LeftCurly"/>
<module name="RightCurly">
<property name="option" value="alone"/>
</module>
<module name="NeedBraces"/>
<module name="AvoidNestedBlocks"/>
-->
<!-- tabs instead of spaces -->
<!--<module name="RegexpSinglelineJava">-->
<!--<property name="format" value="^\t* "/>-->
<!--<property name="message" value="Indent must use tab characters"/>-->
<!--<property name="ignoreComments" value="true"/>-->
<!--</module>-->
<!-- Class Design -->
<!--
<module name="FinalClass"/>
<module name="InterfaceIsType"/>
<module name="MutableException"/>
<module name="InnerTypeLast"/>
<module name="OneTopLevelClass"/>
-->
<!-- Coding -->
<!--
<module name="CovariantEquals"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="InnerAssignment"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<module name="StringLiteralEquality"/>
<module name="NestedForDepth">
<property name="max" value="3"/>
</module>
<module name="NestedIfDepth">
<property name="max" value="3"/>
</module>
<module name="NestedTryDepth">
<property name="max" value="3"/>
</module>
<module name="MultipleVariableDeclarations"/>
<module name="RequireThis">
<property name="checkMethods" value="false"/>
</module>
<module name="OneStatementPerLine"/>
<module name="ExplicitInitialization"/>
<module name="ParameterAssignment"/>
-->
<!-- Imports -->
<module name="AvoidStarImport"/>
<module name="AvoidStaticImport">
<property name="excludes"
value="org.junit.Assert.*,org.mockito.Mockito.*,org.mockito.Matchers.*,org.mockito.ArgumentMatchers.*,
org.hamcrest.Matchers.*,
org.assertj.core.api.Assertions.*,org.hamcrest.CoreMatchers.*,org.hamcrest.core.Is.*,
org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*,
org.springframework.test.web.servlet.result.MockMvcResultMatchers.*,
org.springframework.test.web.servlet.result.MockMvcResultHandlers.*,
junit.framework.TestCase.*,
org.awaitility.Awaitility.*,
org.mockito.BDDMockito.*,
org.springframework.cloud.dataflow.server.single.security.SecurityTestUtils.*,
org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*,
org.springframework.restdocs.operation.preprocess.Preprocessors.*,
org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*,
org.springframework.restdocs.payload.PayloadDocumentation.*,
org.springframework.restdocs.request.RequestDocumentation.*,
org.springframework.restdocs.headers.HeaderDocumentation.*,
org.springframework.restdocs.hypermedia.HypermediaDocumentation.*"/>
</module>
<!--<module name="FallThrough"/>-->
<module name="ImportOrder">
<property name="groups" value="java,/^javax?\./,*,org.springframework"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<!--<module name="IllegalImport">-->
<!--<property name="illegalPkgs" value="org.slf4j"/>-->
<!--</module>-->
<module name="RedundantImport"/>
<!--<module name="ReturnCount">-->
<!--<property name="max" value="0"/>-->
<!--<property name="tokens" value="CTOR_DEF"/>-->
<!--</module>-->
<!--<module name="ReturnCount">-->
<!--<property name="max" value="1"/>-->
<!--<property name="tokens" value="LAMBDA"/>-->
<!--</module>-->
<!--
<module name="ReturnCount">
<property name="max" value="3"/>
<property name="tokens" value="METHOD_DEF"/>
</module>
-->
<module name="UnusedImports"/>
<!-- Miscellaneous -->
<module name="CommentsIndentation"/>
<module name="UpperEll"/>
<module name="ArrayTypeStyle"/>
<module name="OuterTypeFilename"/>
<!-- Modifiers -->
<!--<module name="RedundantModifier"/>-->
<!-- Regexp -->
<!--<module name="RegexpSinglelineJava">-->
<!--<property name="format" value="^\t* +\t*\S"/>-->
<!--<property name="message"-->
<!--value="Line has leading space characters; indentation should be performed with tabs only."/>-->
<!--<property name="ignoreComments" value="true"/>-->
<!--</module>-->
<!--
<module name="Regexp">
<property name="format" value="[ \t]+$"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Trailing whitespace"/>
</module>
<module name="RegexpSinglelineJava">
<property name="maximum" value="0"/>
<property name="format" value="org\.junit\.Assert\.assert"/>
<property name="message"
value="Please use AssertJ imports."/>
<property name="ignoreComments" value="true"/>
</module>
-->
<!-- Whitespace -->
<!--
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter">
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS, ARRAY_DECLARATOR"/>
</module>
<module name="NoWhitespaceBefore"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
-->
</module>
</module>

View File

@@ -0,0 +1,163 @@
/*
* 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 java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* A representation of a binding as defined by the
* <a href="https://github.com/buildpacks/spec/blob/master/extensions/bindings.md">Cloud Native Buildpacks Specification</a>.
*/
public final class Binding {
private final String name;
private final Path path;
private final Map<String, String> metadata;
private final Map<String, String> secret;
/**
* Creates a new {@code Binding} instance using the specified file system root.
*/
public Binding(@NotNull Path path) {
this.name = path.getFileName().toString();
this.path = path;
this.metadata = createFilePerEntryMap(path.resolve("metadata"));
this.secret = createFilePerEntryMap(path.resolve("secret"));
}
/**
* Creates a new {@code Binding} instance using the specified content.
*
* @param name the name of the {@code Binding}.
* @param path the path to the {@code Binding}.
* @param metadata the metadata of the {@code Binding}.
* @param secret the secret of the {@code Binding}.
*/
public Binding(@NotNull String name, @NotNull Path path, @NotNull Map<String, String> metadata,
@NotNull Map<String, String> secret) {
this.name = name;
this.path = path;
this.metadata = metadata;
this.secret = secret;
}
/**
* Returns the name of the binding.
*/
public @NotNull String getName() {
return name;
}
/**
* Returns the path of the binding.
*/
public @NotNull Path getPath() {
return path;
}
/**
* Returns the metadata of the binding.
*/
public @NotNull Map<String, String> getMetadata() {
return metadata;
}
/**
* Returns the secret of the binding.
*/
public @NotNull Map<String, String> getSecret() {
return secret;
}
/**
* Returns the kind of the binding. Equivalent to {@code getMetadata().get("kind")}.
*/
public @NotNull String getKind() {
return metadata.get("kind");
}
/**
* Returns the provider of the binding. Equivalent to {@code getMetadata().get("provider")}.
*/
public @NotNull String getProvider() {
return metadata.get("provider");
}
/**
* Returns the {@link Path} to a metadata file on disk.
*
* @param name the name of the metadata key.
*/
public @NotNull Path getMetadataFilePath(@NotNull String name) {
return this.path.resolve("metadata").resolve(name);
}
/**
* Returns the {@link Path} to a secret file on disk.
*
* @param name the name of the secret key.
*/
public @NotNull Path getSecretFilePath(@NotNull String name) {
return this.path.resolve("secret").resolve(name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Binding binding = (Binding) o;
return name.equals(binding.name) &&
path.equals(binding.path) &&
metadata.equals(binding.metadata) &&
secret.equals(binding.secret);
}
@Override
public int hashCode() {
return Objects.hash(name, path, metadata, secret);
}
private @NotNull Map<String, String> createFilePerEntryMap(@NotNull Path path) {
try {
return Files.list(path)
.collect(Collectors.toMap(
p -> p.getFileName().toString(),
p -> {
try {
return new String(Files.readAllBytes(p), StandardCharsets.UTF_8).trim();
} catch (IOException e) {
throw new IllegalStateException(String.format("unable to read file '%s'", p), e);
}
}
));
} catch (IOException e) {
throw new IllegalStateException(String.format("unable to list children of '%s'", path), e);
}
}
}

View File

@@ -0,0 +1,146 @@
/*
* 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.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* A representation of a collection of bindings as defined by the
* <a href="https://github.com/buildpacks/spec/blob/master/extensions/bindings.md">Cloud Native Buildpacks Specification</a>.
*/
public final class Bindings {
/**
* The name of the environment variable to read to determine the bindings file system root. Specified by the Cloud
* Native Buildpacks Specification.
*/
public static final String CNB_BINDINGS = "CNB_BINDINGS";
private final List<Binding> bindings;
/**
* Creates a new {@code Bindings} instance, using the {@code $CNB_BINDINGS} environment variable to determine the
* file system root. If the {@code $CNB_BINDINGS} environment variable is not set, an empty {@code Bindings} is
* returned. If the directory does not exist, an empty {@code Bindings} is returned.
*/
public Bindings() {
this(System.getenv(CNB_BINDINGS));
}
/**
* Creates a new {@code Bindings} instance, using the specified {@code path}. If the directory does not exist, an
* empty {@code Bindings} is returned.
*
* @param path the path to populate the {@code Bindings} from.
*/
public Bindings(String path) {
if (path == null) {
this.bindings = Collections.emptyList();
return;
}
Path p = Paths.get(path);
if (!Files.exists(p)) {
this.bindings = Collections.emptyList();
return;
}
if (!Files.isDirectory(p)) {
throw new IllegalArgumentException(String.format("%s is not a directory", p));
}
try {
this.bindings = Files.list(p)
.map(Binding::new)
.collect(Collectors.toList());
} catch (IOException e) {
throw new IllegalStateException(String.format("unable to list children of '%s'", path), e);
}
}
Bindings(@NotNull Binding... bindings) {
this.bindings = Arrays.asList(bindings);
}
/**
* Returns all the {@link Binding}s that were found during construction.
*/
public @NotNull List<Binding> getBindings() {
return bindings;
}
/**
* Returns a {@link Binding} with a given name.
*
* @param name the name of the {@code Binding} to find.
* @return the {@code Binding} with a given name if it exists, {@code null} otherwise.
*/
public @Nullable Binding findBinding(@NotNull String name) {
for (Binding binding : bindings) {
if (binding.getName().equalsIgnoreCase(name)) {
return binding;
}
}
return null;
}
/**
* Returns zero or more {@link Binding}s with a given kind. Equivalent to {@link #filterBindings(String, String)}.
*
* @param kind the kind of the {@code Binding} to find.
* @return the collection of {@code Binding}s with a given kind.
*/
public @NotNull List<Binding> filterBindings(@Nullable String kind) {
return filterBindings(kind, null);
}
/**
* Return zero or more {@link Binding}s with a given kind and provider. If {@code kind} or {@code provider} are
* {@code null}, the result is not filtered on that argument.
*
* @param kind the kind of {@code Binding} to find.
* @param provider the provider of {@code Binding} to find
* @return the collection of {@code Binding}s with a given kind and provider.
*/
public @NotNull List<Binding> filterBindings(@Nullable String kind, @Nullable String provider) {
List<Binding> filtered = new ArrayList<>();
for (Binding binding : bindings) {
if ((kind == null || binding.getKind().equalsIgnoreCase(kind)) &&
(provider == null) || binding.getProvider().equalsIgnoreCase(provider)) {
filtered.add(binding);
}
}
return filtered;
}
}

View File

@@ -0,0 +1,112 @@
/*
* 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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.SpringFactoriesLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.springframework.core.env.CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
/**
* An implementation of {@link EnvironmentPostProcessor} that delegates properties generation from {@link Bindings}.
* This implementation generates a single instance of {@code Bindings} and then calls all implementations of
* {@link BindingsPropertiesProcessor} registered with {@link SpringFactoriesLoader} allowing them to generate any
* properties from the contents of the {@code Bindings}.
*/
public final class BindingsEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
/**
* The name of the {@link PropertySource} created by the {@code BindingsEnvironmentPostProcessor}: {@value}.
*/
public static final String BINDINGS_PROPERTY_SOURCE_NAME = "cnbBindings";
final List<BindingsPropertiesProcessor> processors;
private final Log log = LogFactory.getLog(getClass());
private final Bindings bindings;
/**
* Creates a new instance of {@code BindingsEnvironmentPostProcessor} using the {@link Bindings} available in the
* environment and the {@link BindingsPropertiesProcessor}s registered with {@link SpringFactoriesLoader}.
*/
public BindingsEnvironmentPostProcessor() {
this.bindings = new Bindings();
this.processors = SpringFactoriesLoader.
loadFactories(BindingsPropertiesProcessor.class, getClass().getClassLoader());
AnnotationAwareOrderComparator.sort(this.processors);
}
BindingsEnvironmentPostProcessor(@NotNull Bindings bindings,
@NotNull BindingsPropertiesProcessor... processors) {
this.bindings = bindings;
this.processors = Arrays.asList(processors);
}
@Override
public void postProcessEnvironment(@NotNull ConfigurableEnvironment environment,
@NotNull SpringApplication application) {
if (bindings.getBindings().isEmpty()) {
log.debug("No CNB Bindings found. Skipping Environment post-processing.");
return;
}
Map<String, Object> properties = new HashMap<>();
for (BindingsPropertiesProcessor processor : processors) {
processor.process(bindings, properties);
}
if (properties.isEmpty()) {
log.debug("No properties set from CNB Bindings. Skipping PropertySource creation.");
return;
}
log.info("Creating PropertySource from CNB Bindings");
MutablePropertySources propertySources = environment.getPropertySources();
MapPropertySource propertySource = new MapPropertySource(BINDINGS_PROPERTY_SOURCE_NAME, properties);
if (propertySources.contains(COMMAND_LINE_PROPERTY_SOURCE_NAME)) {
propertySources.addAfter(COMMAND_LINE_PROPERTY_SOURCE_NAME, propertySource);
} else {
propertySources.addFirst(propertySource);
}
}
@Override
public int getOrder() {
// Before ConfigFileApplicationListener so values there can use values from {@link Bindings}.
return ConfigFileApplicationListener.DEFAULT_ORDER - 1;
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.springframework.lang.NonNull;
import java.util.Map;
/**
* An interface for types that transform the contents of a {@link Bindings} into properties for injection into a
* {@link org.springframework.core.env.PropertySource}.
*/
@FunctionalInterface
public interface BindingsPropertiesProcessor {
/**
* Transform the currently accumulated {@link Bindings}-related properties.
*
* @param bindings the {@code Bindings} exposed to the application.
* @param properties the currently accumulated properties.
*/
void process(@NonNull Bindings bindings, @NonNull Map<String, Object> properties);
}

View File

@@ -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<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> 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"));
});
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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 Db2BindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "DB2";
@Override
public void process(@NonNull Bindings bindings, @NotNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
properties.put("spring.datasource.driver-class-name", "com.ibm.db2.jcc.DB2Driver");
properties.put("spring.datasource.password", secret.get("password"));
properties.put("spring.datasource.url", String.format("jdbc:db2://%s:%s/%s?user=%s&password=%s",
secret.get("host"), secret.get("port"), secret.get("db"), secret.get("username"),
secret.get("password")));
properties.put("spring.datasource.username", secret.get("username"));
});
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.springframework.lang.NonNull;
import java.util.Map;
/**
* An implementation of {@link BindingsPropertiesProcessor} that detects {@link Binding}s of kind: {@value KIND}.
*/
public final class MongoDbBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "MongoDB";
@Override
public void process(@NonNull Bindings bindings, @NonNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
properties.put("spring.mongodb.uri", secret.get("uri"));
});
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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 MySqlBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "MySQL";
@Override
public void process(@NonNull Bindings bindings, @NotNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
try {
Class.forName("org.mariadb.jdbc.Driver", false, getClass().getClassLoader());
properties.put("spring.datasource.driver-class-name", "org.mariadb.jdbc.Driver");
} catch (ClassNotFoundException e) {
try {
Class.forName("com.mysql.cj.jdbc.Driver", false, getClass().getClassLoader());
properties.put("spring.datasource.driver-class-name", "com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException ignored) {
}
}
properties.put("spring.datasource.password", secret.get("password"));
properties.put("spring.datasource.url", String.format("jdbc:mysql://%s:%s/%s?user=%s&password=%s",
secret.get("host"), secret.get("port"), secret.get("db"), secret.get("username"),
secret.get("password")));
properties.put("spring.datasource.username", secret.get("username"));
});
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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 OracleBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "Oracle";
@Override
public void process(@NonNull Bindings bindings, @NotNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
properties.put("spring.datasource.driver-class-name", "oracle.jdbc.OracleDriver");
properties.put("spring.datasource.password", secret.get("password"));
properties.put("spring.datasource.url", String.format("jdbc:oracle://%s:%s/%s?user=%s&password=%s",
secret.get("host"), secret.get("port"), secret.get("db"), secret.get("username"),
secret.get("password")));
properties.put("spring.datasource.username", secret.get("username"));
});
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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 PostgreSqlBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "PostgreSQL";
@Override
public void process(@NonNull Bindings bindings, @NotNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
properties.put("spring.datasource.driver-class-name", "org.postgresql.Driver");
properties.put("spring.datasource.password", secret.get("password"));
properties.put("spring.datasource.url", String.format("jdbc:postgres://%s:%s/%s?user=%s&password=%s",
secret.get("host"), secret.get("port"), secret.get("db"), secret.get("username"),
secret.get("password")));
properties.put("spring.datasource.username", secret.get("username"));
});
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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 RedisBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "Redis";
@Override
public void process(@NonNull Bindings bindings, @NotNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
properties.put("spring.redis.host", secret.get("hostname"));
properties.put("spring.redis.password", secret.get("password"));
properties.put("spring.redis.port", secret.get("port"));
});
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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 SqlServerBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
/**
* The {@link Binding} kind that this processor is interested in: {@value}.
**/
public static final String KIND = "SQLServer";
@Override
public void process(@NonNull Bindings bindings, @NotNull Map<String, Object> properties) {
bindings.filterBindings(KIND).forEach(binding -> {
Map<String, String> secret = binding.getSecret();
properties.put("spring.datasource.driver-class-name", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
properties.put("spring.datasource.password", secret.get("password"));
properties.put("spring.datasource.url", String.format("jdbc:sqlserver://%s:%s/%s?user=%s&password=%s",
secret.get("host"), secret.get("port"), secret.get("db"), secret.get("username"),
secret.get("password")));
properties.put("spring.datasource.username", secret.get("username"));
});
}
}

View File

@@ -0,0 +1,12 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.bindings.BindingsEnvironmentPostProcessor
# Included implementations
org.springframework.cloud.bindings.BindingsPropertiesProcessor=\
org.springframework.cloud.bindings.CassandraBindingsPropertiesProcessor, \
org.springframework.cloud.bindings.Db2BindingsPropertiesProcessor, \
org.springframework.cloud.bindings.MongoDbBindingsPropertiesProcessor, \
org.springframework.cloud.bindings.MySqlBindingsPropertiesProcessor, \
org.springframework.cloud.bindings.OracleBindingsPropertiesProcessor, \
org.springframework.cloud.bindings.PostgreSqlBindingsPropertiesProcessor, \
org.springframework.cloud.bindings.RedisBindingsPropertiesProcessor, \
org.springframework.cloud.bindings.SqlServerBindingsPropertiesProcessor

View File

@@ -0,0 +1,42 @@
/*
* 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 static org.assertj.core.api.Assertions.assertThat;
@DisplayName("Binding")
final class BindingTest {
@Test
@DisplayName("populates content from filesystem")
void test() {
Binding binding = new Binding(Paths.get("src/test/resources/test-name-1"));
assertThat(binding.getKind()).isEqualTo("test-kind-1");
assertThat(binding.getProvider()).isEqualTo("test-provider-1");
assertThat(binding.getMetadataFilePath("test-key"))
.isEqualTo(Paths.get("src/test/resources/test-name-1/metadata/test-key"));
assertThat(binding.getSecretFilePath("test-key"))
.isEqualTo(Paths.get("src/test/resources/test-name-1/secret/test-key"));
}
}

View File

@@ -0,0 +1,123 @@
/*
* 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 org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.mock.env.MockEnvironment;
import java.nio.file.Paths;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.bindings.BindingsEnvironmentPostProcessor.BINDINGS_PROPERTY_SOURCE_NAME;
@DisplayName("Bindings EnvironmentPostProcessor")
final class BindingsEnvironmentPostProcessorTest {
private final SpringApplication application = new SpringApplication();
private final MockEnvironment environment = new MockEnvironment();
@Test
@DisplayName("does not create PropertySource if no bindings")
void noBindings() {
new BindingsEnvironmentPostProcessor(new Bindings()).postProcessEnvironment(environment, application);
assertThat(environment.getPropertySources()).hasSize(1);
}
@Test
@DisplayName("does not create PropertySource if no properties")
void noProperties() {
new BindingsEnvironmentPostProcessor(
new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.emptyMap(), Collections.emptyMap())
)
).postProcessEnvironment(environment, application);
assertThat(environment.getPropertySources()).hasSize(1);
}
@Test
@DisplayName("creates PropertySource with properties")
void containsProperties() {
new BindingsEnvironmentPostProcessor(
new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.emptyMap(), Collections.emptyMap())
),
(environment, properties) -> properties.put("test-key", "test-value")
).postProcessEnvironment(environment, application);
assertThat(environment.getPropertySources()).hasSize(2);
assertThat(environment.getProperty("test-key")).isEqualTo("test-value");
}
@Test
@DisplayName("adds PropertySource after CommandLinePropertySource")
void withCommandLinePropertySource() {
environment.getPropertySources().addFirst(new SimpleCommandLinePropertySource());
new BindingsEnvironmentPostProcessor(
new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.emptyMap(), Collections.emptyMap())
),
(environment, properties) -> properties.put("test-key", "test-value")
).postProcessEnvironment(environment, application);
PropertySource<?> propertySource = environment.getPropertySources().get(BINDINGS_PROPERTY_SOURCE_NAME);
assertThat(propertySource).isNotNull();
assertThat(environment.getPropertySources().precedenceOf(propertySource)).isEqualTo(1);
}
@Test
@DisplayName("adds PropertySource first")
void withoutCommandLinePropertySource() {
new BindingsEnvironmentPostProcessor(
new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.emptyMap(), Collections.emptyMap())
),
(environment, properties) -> properties.put("test-key", "test-value")
).postProcessEnvironment(environment, application);
PropertySource<?> propertySource = environment.getPropertySources().get(BINDINGS_PROPERTY_SOURCE_NAME);
assertThat(propertySource).isNotNull();
assertThat(environment.getPropertySources().precedenceOf(propertySource)).isEqualTo(0);
}
@Test
@DisplayName("has order before ConfigFileApplicationListener")
void order() {
assertThat(new BindingsEnvironmentPostProcessor(new Bindings()).getOrder())
.isLessThan(ConfigFileApplicationListener.DEFAULT_ORDER);
}
@Test
@DisplayName("included implementations are registered")
void includedImplementations() {
assertThat(new BindingsEnvironmentPostProcessor().processors).hasSize(8);
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@DisplayName("Bindings")
final class BindingsTests {
@Nested
@DisplayName("Constructor")
final class Constructor {
@Test
@DisplayName("empty if path is null")
void nullPath() {
Bindings b = new Bindings((String) null);
assertThat(b.getBindings()).isEmpty();
}
@Test
@DisplayName("empty if path does not exist")
void nonExistentDirectory() {
String path = "src/test/resources/non-existent";
Bindings b = new Bindings(path);
assertThat(b.getBindings()).isEmpty();
}
@Test
@DisplayName("throws exception if path is not a directory")
void nonDirectory() throws IOException {
String path = File.createTempFile("bindings", "").getPath();
assertThatIllegalArgumentException().isThrownBy(() -> new Bindings(path));
}
@Test
@DisplayName("populates content")
void construct() {
String path = "src/test/resources";
Bindings b = new Bindings(path);
assertThat(b.getBindings()).hasSize(2);
}
}
@Nested
@DisplayName("Content")
final class Content {
private final Bindings bindings = new Bindings(
new Binding("test-name-1", Paths.get("src/test/resources/test-name-1"),
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"),
new FluentMap().withEntry("kind", "test-kind-2").withEntry("provider", "test-provider-2"),
Collections.emptyMap())
);
@Test
@DisplayName("returns content")
void getBindings() {
assertThat(bindings.getBindings()).hasSize(2);
}
@Test
@DisplayName("filters bindings by kind")
void filterBindingsByKind() {
assertThat(bindings.filterBindings("test-kind-1", null)).hasSize(1);
}
@Test
@DisplayName("filters bindings by provider")
void filterBindingsByProvider() {
assertThat(bindings.filterBindings(null, "test-provider-1")).hasSize(1);
}
}
}

View File

@@ -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<String, Object> 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");
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.Db2BindingsPropertiesProcessor.KIND;
@DisplayName("DB2 BindingsPropertiesProcessor")
final class Db2BindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new Db2BindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("db", "test-db")
.withEntry("host", "test-host")
.withEntry("password", "test-password")
.withEntry("port", "test-port")
.withEntry("username", "test-username")
)
), properties);
assertThat(properties)
.containsEntry("spring.datasource.driver-class-name", "com.ibm.db2.jcc.DB2Driver")
.containsEntry("spring.datasource.password", "test-password")
.containsEntry("spring.datasource.url",
"jdbc:db2://test-host:test-port/test-db?user=test-username&password=test-password")
.containsEntry("spring.datasource.username", "test-username");
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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 java.util.HashMap;
final class FluentMap extends HashMap<String, String> {
FluentMap withEntry(String key, String value) {
put(key, value);
return this;
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.MongoDbBindingsPropertiesProcessor.KIND;
@DisplayName("MongoDB BindingsPropertiesProcessor")
final class MongoDbBindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new MongoDbBindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("uri", "test-uri")
)
), properties);
assertThat(properties)
.containsEntry("spring.mongodb.uri", "test-uri");
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.MySqlBindingsPropertiesProcessor.KIND;
@DisplayName("MySQL BindingsPropertiesProcessor")
final class MySqlBindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new MySqlBindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("db", "test-db")
.withEntry("host", "test-host")
.withEntry("password", "test-password")
.withEntry("port", "test-port")
.withEntry("username", "test-username")
)
), properties);
assertThat(properties)
.containsEntry("spring.datasource.driver-class-name", "org.mariadb.jdbc.Driver")
.containsEntry("spring.datasource.password", "test-password")
.containsEntry("spring.datasource.url", "jdbc:mysql://test-host:test-port/test-db?user=test-username&password=test-password")
.containsEntry("spring.datasource.username", "test-username");
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.OracleBindingsPropertiesProcessor.KIND;
@DisplayName("Oracle BindingsPropertiesProcessor")
final class OracleBindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new OracleBindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("db", "test-db")
.withEntry("host", "test-host")
.withEntry("password", "test-password")
.withEntry("port", "test-port")
.withEntry("username", "test-username")
)
), properties);
assertThat(properties)
.containsEntry("spring.datasource.driver-class-name", "oracle.jdbc.OracleDriver")
.containsEntry("spring.datasource.password", "test-password")
.containsEntry("spring.datasource.url",
"jdbc:oracle://test-host:test-port/test-db?user=test-username&password=test-password")
.containsEntry("spring.datasource.username", "test-username");
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.PostgreSqlBindingsPropertiesProcessor.KIND;
@DisplayName("PostgreSQL BindingsPropertiesProcessor")
final class PostgreSqlBindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new PostgreSqlBindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("db", "test-db")
.withEntry("host", "test-host")
.withEntry("password", "test-password")
.withEntry("port", "test-port")
.withEntry("username", "test-username")
)
), properties);
assertThat(properties)
.containsEntry("spring.datasource.driver-class-name", "org.postgresql.Driver")
.containsEntry("spring.datasource.password", "test-password")
.containsEntry("spring.datasource.url",
"jdbc:postgres://test-host:test-port/test-db?user=test-username&password=test-password")
.containsEntry("spring.datasource.username", "test-username");
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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.RedisBindingsPropertiesProcessor.KIND;
@DisplayName("Redis BindingsPropertiesProcessor")
final class RedisBindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new RedisBindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("hostname", "test-hostname")
.withEntry("password", "test-password")
.withEntry("port", "test-port")
)
), properties);
assertThat(properties)
.containsEntry("spring.redis.host", "test-hostname")
.containsEntry("spring.redis.password", "test-password")
.containsEntry("spring.redis.port", "test-port");
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.SqlServerBindingsPropertiesProcessor.KIND;
@DisplayName("SQLServer BindingsPropertiesProcessor")
final class SqlServerBindingsPropertiesProcessorTest {
@Test
@DisplayName("contributes properties")
void test() {
HashMap<String, Object> properties = new HashMap<>();
new SqlServerBindingsPropertiesProcessor().process(new Bindings(
new Binding("test-name", Paths.get("test-path"),
Collections.singletonMap("kind", KIND),
new FluentMap()
.withEntry("db", "test-db")
.withEntry("host", "test-host")
.withEntry("password", "test-password")
.withEntry("port", "test-port")
.withEntry("username", "test-username")
)
), properties);
assertThat(properties)
.containsEntry("spring.datasource.driver-class-name", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
.containsEntry("spring.datasource.password", "test-password")
.containsEntry("spring.datasource.url",
"jdbc:sqlserver://test-host:test-port/test-db?user=test-username&password=test-password")
.containsEntry("spring.datasource.username", "test-username");
}
}

View File

@@ -0,0 +1 @@
test-kind-1

View File

@@ -0,0 +1 @@
test-provider-1

View File

@@ -0,0 +1 @@
test-value

View File

@@ -0,0 +1 @@
test-kind-2

View File

@@ -0,0 +1 @@
test-provider-2

View File

@@ -0,0 +1 @@
test-value