This time, the same kinds of simplifcations before.  Also added the two
methods that we added in libcnb.

Signed-off-by: Ben Hale <bhale@vmware.com>
This commit is contained in:
Ben Hale
2020-05-08 18:04:34 -07:00
parent 71bfec3084
commit d3fd15f790
26 changed files with 269 additions and 274 deletions

View File

@@ -15,21 +15,21 @@
*/
package org.springframework.cloud.cnb.boot;
import java.util.Map;
import org.springframework.cloud.cnb.core.Binding;
import org.springframework.cloud.cnb.core.CnbBinding;
import java.util.Map;
public class CassandraCnbBindingProcessor implements CnbBindingProcessor {
public static final String CASSANDRA_KIND = "cassandra";
@Override
public boolean accept(CnbBinding binding) {
public boolean accept(Binding binding) {
return binding.getKind().equals(CASSANDRA_KIND);
}
@Override
public void process(CnbBinding binding, Map<String, Object> properties) {
public void process(Binding binding, Map<String, Object> 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"));

View File

@@ -17,13 +17,13 @@ package org.springframework.cloud.cnb.boot;
import java.util.Map;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public interface CnbBindingProcessor {
boolean accept(CnbBinding binding);
boolean accept(Binding binding);
void process(CnbBinding binding, Map<String, Object> properties);
void process(Binding binding, Map<String, Object> properties);
CnbBindingProcessorProperties getProperties();
}

View File

@@ -25,7 +25,7 @@ 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.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import org.springframework.cloud.cnb.core.Bindings;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
@@ -80,20 +80,20 @@ public class CnbBindingsPostProcessor implements EnvironmentPostProcessor, Order
Bindings bindings = CNBBindingsSingleton.getCnbBindingsInstance();
if (bindings.hasBindings()) {
List<CnbBinding> allBindings = bindings.findAllBindings();
List<Binding> allBindings = bindings.findAllBindings();
List<CnbBindingProcessor> cnbBindingProcessors = SpringFactoriesLoader
.loadFactories(CnbBindingProcessor.class, getClass().getClassLoader());
AnnotationAwareOrderComparator.sort(cnbBindingProcessors);
for (CnbBindingProcessor processor : cnbBindingProcessors) {
List<CnbBinding> cnbBindings = allBindings.stream()
List<Binding> cnbBindings = allBindings.stream()
.filter(processor::accept)
.collect(Collectors.toList());
if (cnbBindings.size() == 1) {
CnbBinding binding = cnbBindings.get(0);
Binding binding = cnbBindings.get(0);
Map<String, Object> properties = new LinkedHashMap<>();
processor.process(binding, properties);

View File

@@ -17,18 +17,18 @@ package org.springframework.cloud.cnb.boot;
import java.util.Map;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import org.springframework.cloud.cnb.jdbc.JdbcBinding;
public class DataSourceCnbBindingProcessor implements CnbBindingProcessor {
@Override
public boolean accept(CnbBinding binding) {
public boolean accept(Binding binding) {
return JdbcBinding.isJDCBBinding(binding);
}
@Override
public void process(CnbBinding binding, Map<String, Object> properties) {
public void process(Binding binding, Map<String, Object> properties) {
JdbcBinding jdbcBinding = new JdbcBinding(binding);
properties.put("spring.datasource.url", jdbcBinding.getJdbcUrl());
properties.put("spring.datasource.username", jdbcBinding.getUsername());

View File

@@ -17,18 +17,18 @@ package org.springframework.cloud.cnb.boot;
import java.util.Map;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class MongoCnbBindingProcessor implements CnbBindingProcessor {
private static final String MONGO_KIND = "mongodb";
@Override
public boolean accept(CnbBinding binding) {
public boolean accept(Binding binding) {
return binding.getKind().equals(MONGO_KIND);
}
@Override
public void process(CnbBinding binding, Map<String, Object> properties) {
public void process(Binding binding, Map<String, Object> properties) {
properties.put("spring.redis.mongodb.uri", binding.getSecret().get("uri"));
// TODO: build uri from discrete fields?

View File

@@ -17,7 +17,7 @@ package org.springframework.cloud.cnb.boot;
import java.util.Map;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class RedisCnbBindingProcessor implements CnbBindingProcessor {
@@ -25,12 +25,12 @@ public class RedisCnbBindingProcessor implements CnbBindingProcessor {
public static final String REDIS_KIND = "redis";
@Override
public boolean accept(CnbBinding binding) {
public boolean accept(Binding binding) {
return binding.getKind().equals(REDIS_KIND);
}
@Override
public void process(CnbBinding binding, Map<String, Object> properties) {
public void process(Binding binding, Map<String, Object> properties) {
properties.put("spring.redis.host", binding.getSecret().get("hostname")); //TODO: also support "host"
properties.put("spring.redis.port", binding.getSecret().get("port")); //TODO: handle missing
properties.put("spring.redis.password", binding.getSecret().get("password")); //TODO: handle missing

View File

@@ -20,7 +20,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import static org.assertj.core.api.Assertions.assertThat;
@@ -32,7 +32,7 @@ public class CassandraCnbBindingProcessorTests {
CassandraCnbBindingProcessor bindingProcessor = new CassandraCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "cassandra");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isTrue();
}
@@ -41,7 +41,7 @@ public class CassandraCnbBindingProcessorTests {
CassandraCnbBindingProcessor bindingProcessor = new CassandraCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "mysql");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isFalse();
}
@@ -55,7 +55,7 @@ public class CassandraCnbBindingProcessorTests {
bindingSecret.put("node_ips", "10.0.4.35,10.0.4.36");
bindingSecret.put("password", "some-password");
bindingSecret.put("username", "some-username");
CnbBinding binding = new CnbBinding(bindingMetadata, bindingSecret);
Binding binding = new Binding(bindingMetadata, bindingSecret);
Map<String,Object> properties = new HashMap<String,Object>();
bindingProcessor.process(binding, properties);
assertThat(properties.get("spring.data.cassandra.username")).isEqualTo("some-username");

View File

@@ -21,7 +21,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,7 +33,7 @@ public class DataSourceCnbBindingProcessorTests {
DataSourceCnbBindingProcessor bindingProcessor = new DataSourceCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "mysql");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isTrue();
}
@@ -42,7 +42,7 @@ public class DataSourceCnbBindingProcessorTests {
DataSourceCnbBindingProcessor bindingProcessor = new DataSourceCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "redis");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isFalse();
}
@@ -57,7 +57,7 @@ public class DataSourceCnbBindingProcessorTests {
bindingSecret.put("db", "some-db");
bindingSecret.put("username", "some-username");
bindingSecret.put("password", "some-password");
CnbBinding binding = new CnbBinding(bindingMetadata, bindingSecret);
Binding binding = new Binding(bindingMetadata, bindingSecret);
Map<String,Object> properties = new HashMap<String,Object>();
bindingProcessor.process(binding, properties);
assertThat(properties.get("spring.datasource.url")).isEqualTo("jdbc:testscheme://10.0.4.35:3306/some-db?user=some-username&password=some-password");

View File

@@ -21,7 +21,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,7 +33,7 @@ public class MongoCnbBindingProcessorTests {
MongoCnbBindingProcessor bindingProcessor = new MongoCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "mongodb");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isTrue();
}
@@ -42,7 +42,7 @@ public class MongoCnbBindingProcessorTests {
MongoCnbBindingProcessor bindingProcessor = new MongoCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "mysql");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isFalse();
}
@@ -53,7 +53,7 @@ public class MongoCnbBindingProcessorTests {
bindingMetadata.put("kind", "mongodb");
Map<String,String> bindingSecret = new HashMap<String,String>();
bindingSecret.put("uri", "some-uri");
CnbBinding binding = new CnbBinding(bindingMetadata, bindingSecret);
Binding binding = new Binding(bindingMetadata, bindingSecret);
Map<String,Object> properties = new HashMap<String,Object>();
bindingProcessor.process(binding, properties);
assertThat(properties.get("spring.redis.mongodb.uri")).isEqualTo("some-uri");

View File

@@ -21,7 +21,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,7 +33,7 @@ public class RedisCnbBindingProcessorTests {
RedisCnbBindingProcessor bindingProcessor = new RedisCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "redis");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isTrue();
}
@@ -42,7 +42,7 @@ public class RedisCnbBindingProcessorTests {
RedisCnbBindingProcessor bindingProcessor = new RedisCnbBindingProcessor();
Map<String, String> bindingMetadata = new HashMap<String, String>();
bindingMetadata.put("kind", "mysql");
CnbBinding binding = new CnbBinding(bindingMetadata, new HashMap<String, String>());
Binding binding = new Binding(bindingMetadata, new HashMap<String, String>());
assertThat(bindingProcessor.accept(binding)).isFalse();
}
@@ -55,7 +55,7 @@ public class RedisCnbBindingProcessorTests {
bindingSecret.put("hostname", "10.0.4.35");
bindingSecret.put("port", "6379");
bindingSecret.put("password", "some-password");
CnbBinding binding = new CnbBinding(bindingMetadata, bindingSecret);
Binding binding = new Binding(bindingMetadata, bindingSecret);
Map<String,Object> properties = new HashMap<String,Object>();
bindingProcessor.process(binding, properties);
assertThat(properties.get("spring.redis.host")).isEqualTo("10.0.4.35");

View File

@@ -15,13 +15,13 @@
*/
package org.springframework.cloud.cnb.boot.test;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import org.springframework.cloud.cnb.jdbc.JdbcKind;
public class TestJdbcKind implements JdbcKind {
@Override
public boolean forBinding(CnbBinding binding) {
public boolean forBinding(Binding binding) {
if (binding.getKind().equals("test-kind")) {
return true;
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.cloud.cnb.jdbc;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class DB2JdbcKind implements JdbcKind{
@@ -23,7 +23,7 @@ public class DB2JdbcKind implements JdbcKind{
public static final String DB2_SCHEME = "db2";
@Override
public boolean forBinding(CnbBinding binding) {
public boolean forBinding(Binding binding) {
return binding.getKind().equals(DB2_KIND);
}

View File

@@ -17,16 +17,16 @@ package org.springframework.cloud.cnb.jdbc;
import java.util.ServiceLoader;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import org.springframework.cloud.cnb.core.IllegalBindingException;
public class JdbcBinding {
private static final String JDBC_PREFIX = "jdbc:";
private final CnbBinding binding;
private final Binding binding;
private final JdbcKind kind;
public static boolean isJDCBBinding(CnbBinding binding) {
public static boolean isJDCBBinding(Binding binding) {
ServiceLoader<JdbcKind> loader = ServiceLoader.load(JdbcKind.class);
for (JdbcKind kind : loader) {
if (kind.forBinding(binding)) {
@@ -36,7 +36,7 @@ public class JdbcBinding {
return false;
}
public JdbcBinding(CnbBinding binding) {
public JdbcBinding(Binding binding) {
ServiceLoader<JdbcKind> loader = ServiceLoader.load(JdbcKind.class);
for (JdbcKind kind : loader) {
if (kind.forBinding(binding)) {

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.cloud.cnb.jdbc;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public interface JdbcKind {
boolean forBinding(CnbBinding binding);
boolean forBinding(Binding binding);
String getScheme();
String getDriverClassName();
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.cloud.cnb.jdbc;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class MysqlJdbcKind implements JdbcKind{
@@ -23,7 +23,7 @@ public class MysqlJdbcKind implements JdbcKind{
public static final String MYSQL_SCHEME = "mysql";
@Override
public boolean forBinding(CnbBinding binding) {
public boolean forBinding(Binding binding) {
return binding.getKind().equals(MYSQL_KIND);
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.cloud.cnb.jdbc;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class OracleJdbcKind implements JdbcKind{
@@ -23,7 +23,7 @@ public class OracleJdbcKind implements JdbcKind{
public static final String ORACLE_SCHEME = "oracle";
@Override
public boolean forBinding(CnbBinding binding) {
public boolean forBinding(Binding binding) {
return binding.getKind().equals(ORACLE_KIND);
}

View File

@@ -18,7 +18,7 @@ package org.springframework.cloud.cnb.jdbc;
import java.util.Arrays;
import java.util.List;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class PostgresJdbcKind implements JdbcKind{
@@ -27,7 +27,7 @@ public class PostgresJdbcKind implements JdbcKind{
public static final String POSTGRES_SCHEME = "postgres";
@Override
public boolean forBinding(CnbBinding binding) {
public boolean forBinding(Binding binding) {
return POSTGRES_KINDS.contains(binding.getKind());
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.cloud.cnb.jdbc;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
public class SqlServerJdbcKind implements JdbcKind{
@@ -23,7 +23,7 @@ public class SqlServerJdbcKind implements JdbcKind{
public static final String SQLSERVER_SCHEME = "sqlserver";
@Override
public boolean forBinding(CnbBinding binding) {
public boolean forBinding(Binding binding) {
return binding.getKind().equals(SQLSERVER_KIND);
}

View File

@@ -20,7 +20,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.cloud.cnb.core.CnbBinding;
import org.springframework.cloud.cnb.core.Binding;
import static org.assertj.core.api.Assertions.assertThat;
@@ -29,13 +29,13 @@ public class JdbcBindingTest {
@Test
public void testIsJdbcBinding_false() {
CnbBinding notJdbcBinding = bindingWithKind("not-registered");
Binding notJdbcBinding = bindingWithKind("not-registered");
assertThat(JdbcBinding.isJDCBBinding(notJdbcBinding)).isFalse();
}
@Test
public void testJdbcBinding_mysql() {
CnbBinding mysqlBinding = bindingWithKind("mysql");
Binding mysqlBinding = bindingWithKind("mysql");
assertThat(JdbcBinding.isJDCBBinding(mysqlBinding)).isTrue();
JdbcBinding jdbcBinding = new JdbcBinding(mysqlBinding);
assertThat(jdbcBinding.getJdbcUrl()).
@@ -44,7 +44,7 @@ public class JdbcBindingTest {
@Test
public void testJdbcBinding_db2() {
CnbBinding db2Binding = bindingWithKind("db2");
Binding db2Binding = bindingWithKind("db2");
assertThat(JdbcBinding.isJDCBBinding(db2Binding)).isTrue();
JdbcBinding jdbcBinding = new JdbcBinding(db2Binding);
@@ -56,7 +56,7 @@ public class JdbcBindingTest {
@Test
public void testJdbcBinding_oracle() {
CnbBinding oracleBinding = bindingWithKind("oracle");
Binding oracleBinding = bindingWithKind("oracle");
assertThat(JdbcBinding.isJDCBBinding(oracleBinding)).isTrue();
JdbcBinding jdbcBinding = new JdbcBinding(oracleBinding);
assertThat(jdbcBinding.getJdbcUrl())
@@ -67,7 +67,7 @@ public class JdbcBindingTest {
@Test
public void testJdbcBinding_postgres() {
CnbBinding postgresBinding = bindingWithKind("postgres");
Binding postgresBinding = bindingWithKind("postgres");
assertThat(JdbcBinding.isJDCBBinding(postgresBinding)).isTrue();
JdbcBinding jdbcBinding = new JdbcBinding(postgresBinding);
assertThat(jdbcBinding.getJdbcUrl())
@@ -78,7 +78,7 @@ public class JdbcBindingTest {
@Test
public void testJdbcBinding_postgresql() {
CnbBinding postgresBinding = bindingWithKind("postgresql");
Binding postgresBinding = bindingWithKind("postgresql");
assertThat(JdbcBinding.isJDCBBinding(postgresBinding)).isTrue();
JdbcBinding jdbcBinding = new JdbcBinding(postgresBinding);
assertThat(jdbcBinding.getJdbcUrl())
@@ -89,7 +89,7 @@ public class JdbcBindingTest {
@Test
public void testJdbcBinding_sqlserver() {
CnbBinding sqlserverBinding = bindingWithKind("sqlserver");
Binding sqlserverBinding = bindingWithKind("sqlserver");
assertThat(JdbcBinding.isJDCBBinding(sqlserverBinding)).isTrue();
JdbcBinding jdbcBinding = new JdbcBinding(sqlserverBinding);
assertThat(jdbcBinding.getJdbcUrl())
@@ -98,7 +98,7 @@ public class JdbcBindingTest {
isEqualTo("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
public CnbBinding bindingWithKind(String kind) {
public Binding bindingWithKind(String kind) {
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("kind", kind);
Map<String, String> secret = new HashMap<String, String>();
@@ -107,6 +107,6 @@ public class JdbcBindingTest {
secret.put("db", "some-db");
secret.put("username", "some-username");
secret.put("password", "some-password");
return new CnbBinding(metadata, secret);
return new Binding(metadata, secret);
}
}

View File

@@ -0,0 +1,163 @@
/*
* 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.core;
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

@@ -19,7 +19,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -42,7 +41,7 @@ public final class Bindings {
*/
public static final String CNB_BINDINGS = "CNB_BINDINGS";
private final List<CnbBinding> bindings;
private final List<Binding> bindings;
/**
* Creates a new {@code Bindings} instance, using the {@code $CNB_BINDINGS} environment variable to determine the
@@ -69,10 +68,10 @@ public final class Bindings {
} else {
try {
this.bindings = Files.list(p)
.map(c -> new CnbBinding(c))
.map(Binding::new)
.collect(Collectors.toList());
} catch (IOException e) {
throw new UndeclaredThrowableException(e);
throw new IllegalStateException(String.format("unable to list children of '%s'", path), e);
}
}
}
@@ -90,14 +89,21 @@ public final class Bindings {
return environment.containsKey(CNB_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 CnbBinding findBinding(@NotNull String name) {
for (CnbBinding binding : this.bindings) {
public @Nullable Binding findBinding(@NotNull String name) {
for (Binding binding : bindings) {
if (binding.getName().equals(name)) {
return binding;
}
@@ -107,20 +113,13 @@ public final class Bindings {
}
/**
* Returns all the {@link Binding}s that were found during construction.
*/
public @NotNull List<CnbBinding> findBindings() {
return this.bindings;
}
/**
* Returns zero or more {@link Binding}s with a given kind. Equivalent to {@link #findBindings(String, String)}.
* Returns zero or more {@link Binding}s with a given kind. Equivalent to {@link #getBindings(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<CnbBinding> findBindings(@Nullable String kind) {
return findBindings(kind, null);
public @NotNull List<Binding> getBindings(@Nullable String kind) {
return getBindings(kind, null);
}
/**
@@ -131,18 +130,18 @@ public final class Bindings {
* @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<CnbBinding> findBindings(@Nullable String kind, @Nullable String provider) {
List<CnbBinding> bindings = new ArrayList<>();
public @NotNull List<Binding> getBindings(@Nullable String kind, @Nullable String provider) {
List<Binding> filtered = new ArrayList<>();
for (CnbBinding binding : this.bindings) {
for (Binding binding : bindings) {
if ((kind == null || binding.getKind().equals(kind)) &&
(provider == null) || binding.getProvider().equals(provider)) {
bindings.add(binding);
filtered.add(binding);
}
}
return bindings;
return filtered;
}
}

View File

@@ -1,37 +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.core;
/**
* JVM singleton for cases where you want to avoid reparsing the JSON per instance of {@code CfEnv}
* @author Mark Pollack
*/
public final class CNBBindingsSingleton {
private static Bindings INSTANCE;
private CNBBindingsSingleton() {
}
public synchronized static Bindings getCnbBindingsInstance() {
if (INSTANCE == null) {
INSTANCE = new Bindings();
}
return INSTANCE;
}
}

View File

@@ -1,95 +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.core;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CnbBinding {
private final Map<String, String> metadata;
private final Map<String, String> secret;
private String name;
private File bindingDir;
public CnbBinding(Map<String, String> metadata, Map<String, String> secret) {
this.metadata = metadata;
this.secret = secret;
}
public CnbBinding(File bindingDir) {
this.bindingDir = bindingDir;
this.metadata = subDirToMap("metadata");
this.secret = subDirToMap("secret");
this.name = bindingDir.getName();
}
public String getName() {
return this.name;
}
public Map<String, String> getSecret() {
return this.secret;
}
public Map<String, String> getAllMetadata() {
return this.metadata;
}
public String getKind() {
return this.metadata.get("kind");
}
public String getProvider() {
return this.metadata.get("provider");
}
public String[] getTags() {
String tagsVal = this.metadata.get("tags");
String[] tags = tagsVal.split(",");
return tags;
}
private Map<String, String> subDirToMap(String subdir) {
Path subDirPath = Paths.get(this.bindingDir.getPath(), subdir);
File subDir = subDirPath.toFile().getAbsoluteFile();
if (!subDir.isDirectory()) {
throw new IllegalBindingException(subDir + "is not a directory");
}
Map<String, String> secret = new HashMap<String, String>();
for (File file : subDir.listFiles()) {
if (file.isDirectory()) {
continue;
}
secret.put(file.getName(), readFile(file));
}
return secret;
}
private String readFile(File file) {
try {
return new String(Files.readAllBytes(file.toPath())).trim();
} catch (IOException e) {
throw new IllegalBindingException(e);
}
}
}

View File

@@ -1,32 +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.core;
public class IllegalBindingException extends RuntimeException {
public IllegalBindingException(String message) {
super(message);
}
public IllegalBindingException(Throwable cause) {
super(cause);
}
public IllegalBindingException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -16,27 +16,24 @@
package org.springframework.cloud.cnb.core;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.cnb.core.test.EnvMock;
import java.nio.file.Paths;
import static org.assertj.core.api.Assertions.assertThat;
final class BindingTest {
public class CnbBindingsHasBindingsTests {
@Test
void test() {
Binding binding = new Binding(Paths.get("src/test/resources/test-name-1"));
@Test
public void testHasBindings() {
new EnvMock("some/path");
Bindings bindings = new Bindings();
assertThat(bindings.hasBindings()).isTrue();
}
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"));
}
@Test
@Ignore
public void testHasBindingsFalse() {
Bindings bindings = new Bindings();
assertThat(bindings.hasBindings()).isFalse();
}
}

View File

@@ -22,23 +22,23 @@ import java.io.IOException;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
public class BindingsTests {
final class BindingsTests {
@Test
void constructFromNonExistentDirectory() {
String path = "src/test/resources/non-existent";
Bindings b = new Bindings(path);
assertThat(b.findBindings()).isEmpty();
assertThat(b.getBindings()).isEmpty();
}
@Test
void constructFromNonDirectory() throws IOException {
String path = File.createTempFile("bindings", "").getPath();
Bindings b = new Bindings(path);
assertThat(b.findBindings()).isEmpty();
assertThatIllegalArgumentException().isThrownBy(() -> new Bindings(path));
}
@Test
@@ -46,7 +46,7 @@ public class BindingsTests {
String path = "src/test/resources";
Bindings b = new Bindings(path);
assertThat(b.findBindings()).hasSize(2);
assertThat(b.getBindings()).hasSize(2);
}
@Test
@@ -56,11 +56,11 @@ public class BindingsTests {
}
@Test
void getAllBindings() {
void getBindings() {
String path = "src/test/resources";
Bindings b = new Bindings(path);
assertThat(b.findBindings()).hasSize(2);
assertThat(b.getBindings()).hasSize(2);
}
@Test
@@ -68,7 +68,7 @@ public class BindingsTests {
String path = "src/test/resources";
Bindings b = new Bindings(path);
assertThat(b.findBindings("test-kind-1", null)).containsExactly(new Binding());
assertThat(b.getBindings("test-kind-1", null)).hasSize(1);
}
@Test
@@ -76,7 +76,7 @@ public class BindingsTests {
String path = "src/test/resources";
Bindings b = new Bindings(path);
assertThat(b.findBindings(null, "test-provider-1")).containsExactly(new Binding());
assertThat(b.getBindings(null, "test-provider-1")).hasSize(1);
}
}