Add capability to find an optional user by name.
Resolves gh-44.
This commit is contained in:
@@ -34,6 +34,7 @@ import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.geode.core.env.support.CloudCacheService;
|
||||
import org.springframework.geode.core.env.support.Service;
|
||||
import org.springframework.geode.core.env.support.User;
|
||||
@@ -52,6 +53,7 @@ import org.springframework.util.StringUtils;
|
||||
* @see java.net.URL
|
||||
* @see java.util.Properties
|
||||
* @see java.util.function.Predicate
|
||||
* @see org.springframework.core.env.ConfigurableEnvironment
|
||||
* @see org.springframework.core.env.EnumerablePropertySource
|
||||
* @see org.springframework.core.env.Environment
|
||||
* @see org.springframework.core.env.PropertiesPropertySource
|
||||
@@ -72,9 +74,11 @@ public class VcapPropertySource extends PropertySource<EnumerablePropertySource<
|
||||
private static final String VCAP_APPLICATION_URIS_PROPERTY = VCAP_APPLICATION_PROPERTY + "uris";
|
||||
private static final String VCAP_PROPERTY_SOURCE_NAME = "vcap";
|
||||
private static final String VCAP_SERVICES_PROPERTY = "vcap.services.";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_GFSH_URL_PROPERTY = VCAP_SERVICES_PROPERTY + "%s.credentials.urls.gfsh";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_LOCATORS_PROPERTY = VCAP_SERVICES_PROPERTY + "%s.credentials.locators";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_USERS_PROPERTY = VCAP_SERVICES_PROPERTY + "%s.credentials.users[%d]";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_NAME_PROPERTY = VCAP_SERVICES_PROPERTY + "%s.name";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_URL_GFSH_PROPERTY = VCAP_SERVICES_PROPERTY + "%s.credentials.urls.gfsh";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_USERS_PROPERTY = VCAP_SERVICES_PROPERTY + "%s.credentials.users";
|
||||
private static final String VCAP_SERVICES_SERVICE_NAME_USERS_INDEX_PROPERTY = VCAP_SERVICES_SERVICE_NAME_USERS_PROPERTY + "[%d]";
|
||||
|
||||
private static final Predicate<Object> CLOUD_CACHE_SERVICE_PREDICATE =
|
||||
propertyValue -> String.valueOf(propertyValue).toLowerCase().contains(CLOUD_CACHE_TAG_NAME);
|
||||
@@ -152,7 +156,7 @@ public class VcapPropertySource extends PropertySource<EnumerablePropertySource<
|
||||
|
||||
protected Set<String> findAllPropertiesByNameMatching(Iterable<String> properties, Predicate<String> predicate) {
|
||||
|
||||
return StreamSupport.stream(properties.spliterator(), false)
|
||||
return StreamSupport.stream(CollectionUtils.nullSafeIterable(properties).spliterator(), false)
|
||||
.filter(predicate)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
@@ -163,7 +167,7 @@ public class VcapPropertySource extends PropertySource<EnumerablePropertySource<
|
||||
|
||||
protected Set<String> findAllPropertiesByValueMatching(Iterable<String> properties, Predicate<Object> predicate) {
|
||||
|
||||
return StreamSupport.stream(properties.spliterator(), false)
|
||||
return StreamSupport.stream(CollectionUtils.nullSafeIterable(properties).spliterator(), false)
|
||||
.filter(propertyName -> predicate.test(getProperty(propertyName)))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
@@ -207,7 +211,7 @@ public class VcapPropertySource extends PropertySource<EnumerablePropertySource<
|
||||
.filter(StringUtils::hasText)
|
||||
.ifPresent(service::withLocators);
|
||||
|
||||
Object gfshUrl = getProperty(String.format(VCAP_SERVICES_SERVICE_NAME_GFSH_URL_PROPERTY, service));
|
||||
Object gfshUrl = getProperty(String.format(VCAP_SERVICES_SERVICE_NAME_URL_GFSH_PROPERTY, service));
|
||||
|
||||
Optional.ofNullable(gfshUrl)
|
||||
.map(String::valueOf)
|
||||
@@ -246,35 +250,83 @@ public class VcapPropertySource extends PropertySource<EnumerablePropertySource<
|
||||
.orElseThrow(() -> newIllegalStateException("No service with tags [%s] was found", tags));
|
||||
}
|
||||
|
||||
public Optional<User> findFirstUserByRoleClusterOperator(Service service) {
|
||||
public Optional<User> findUserByName(Service service, String targetUsername) {
|
||||
|
||||
Assert.hasText(targetUsername, String.format("Target username [%s] is required", targetUsername));
|
||||
|
||||
Optional<User> optionalUser = Optional.empty();
|
||||
|
||||
String serviceName = service.getName();
|
||||
String userPropertyName = String.format(VCAP_SERVICES_SERVICE_NAME_USERS_PROPERTY, serviceName, 0);
|
||||
String userPropertyName = String.format(VCAP_SERVICES_SERVICE_NAME_USERS_INDEX_PROPERTY, serviceName, 0);
|
||||
|
||||
for (int index = 1; containsProperty(userPropertyName+".roles"); index++) {
|
||||
for (int index = 1; containsProperty(asUserUsernameProperty(userPropertyName)); index++) {
|
||||
|
||||
String roles = String.valueOf(getProperty(userPropertyName+".roles"));
|
||||
String username = String.valueOf(getProperty(asUserUsernameProperty(userPropertyName)));
|
||||
|
||||
if (username.equals(targetUsername)) {
|
||||
break;
|
||||
}
|
||||
|
||||
userPropertyName = String.format(VCAP_SERVICES_SERVICE_NAME_USERS_INDEX_PROPERTY, serviceName, index);
|
||||
}
|
||||
|
||||
if (containsProperty(asUserUsernameProperty(userPropertyName))) {
|
||||
|
||||
String username = String.valueOf(getProperty(asUserUsernameProperty(userPropertyName)));
|
||||
String password = String.valueOf(getProperty(asUserPasswordProperty(userPropertyName)));
|
||||
|
||||
User user = User.with(username)
|
||||
.withPassword(password);
|
||||
|
||||
optionalUser = Optional.of(user);
|
||||
}
|
||||
|
||||
return optionalUser;
|
||||
}
|
||||
|
||||
public Optional<User> findFirstUserByRoleClusterOperator(Service service) {
|
||||
|
||||
Optional<User> optionalUser = Optional.empty();
|
||||
|
||||
String serviceName = service.getName();
|
||||
String userPropertyName = String.format(VCAP_SERVICES_SERVICE_NAME_USERS_INDEX_PROPERTY, serviceName, 0);
|
||||
|
||||
for (int index = 1; containsProperty(asUserRolesProperty(userPropertyName)); index++) {
|
||||
|
||||
String roles = String.valueOf(getProperty(asUserRolesProperty(userPropertyName)));
|
||||
|
||||
if (roles.contains(User.Role.CLUSTER_OPERATOR.name().toLowerCase())) {
|
||||
break;
|
||||
}
|
||||
|
||||
userPropertyName = String.format(VCAP_SERVICES_SERVICE_NAME_USERS_PROPERTY, serviceName, index);
|
||||
userPropertyName = String.format(VCAP_SERVICES_SERVICE_NAME_USERS_INDEX_PROPERTY, serviceName, index);
|
||||
}
|
||||
|
||||
if (containsProperty(userPropertyName+".username")) {
|
||||
if (containsProperty(asUserUsernameProperty(userPropertyName))) {
|
||||
|
||||
String username = String.valueOf(getProperty(userPropertyName+".username"));
|
||||
String password = String.valueOf(getProperty(userPropertyName+".password"));
|
||||
String username = String.valueOf(getProperty(asUserUsernameProperty(userPropertyName)));
|
||||
String password = String.valueOf(getProperty(asUserPasswordProperty(userPropertyName)));
|
||||
|
||||
User user = User.with(username)
|
||||
.withPassword(password)
|
||||
.withRole(User.Role.CLUSTER_OPERATOR);
|
||||
|
||||
return Optional.of(user);
|
||||
optionalUser = Optional.of(user);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
return optionalUser;
|
||||
}
|
||||
|
||||
private String asUserPasswordProperty(String userProperty) {
|
||||
return String.format("%s.password", userProperty);
|
||||
}
|
||||
|
||||
private String asUserRolesProperty(String userProperty) {
|
||||
return String.format("%s.roles", userProperty);
|
||||
}
|
||||
|
||||
private String asUserUsernameProperty(String userProperty) {
|
||||
return String.format("%s.username", userProperty);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -51,13 +51,20 @@ import org.springframework.geode.core.env.support.User;
|
||||
* Unit tests for {@link VcapPropertySource}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.net.URL
|
||||
* @see java.util.Properties
|
||||
* @see java.util.function.Predicate
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.core.env.ConfigurableEnvironment
|
||||
* @see org.springframework.core.env.EnumerablePropertySource
|
||||
* @see org.springframework.core.env.Environment
|
||||
* @see org.springframework.core.env.PropertiesPropertySource
|
||||
* @see org.springframework.core.env.PropertySource
|
||||
* @see org.springframework.geode.core.env.VcapPropertySource
|
||||
* @see org.springframework.geode.core.env.support.CloudCacheService
|
||||
* @see org.springframework.geode.core.env.support.Service
|
||||
* @see org.springframework.geode.core.env.support.User
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class VcapPropertySourceUnitTests {
|
||||
@@ -355,7 +362,7 @@ public class VcapPropertySourceUnitTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findTargetVcapApplicationPropertiesIsSuccessful() {
|
||||
public void findTargetVcapServicePropertiesIsSuccessful() {
|
||||
|
||||
EnumerablePropertySource mockPropertySource = mock(EnumerablePropertySource.class);
|
||||
|
||||
@@ -609,29 +616,134 @@ public class VcapPropertySourceUnitTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findFirstUserByRoleClusterOperatorReturnsUser() {
|
||||
public void findUserByNameReturnsOptionalOfUser() {
|
||||
|
||||
Properties vcap = new Properties();
|
||||
|
||||
vcap.setProperty("vcap.application.name", "boot-example");
|
||||
vcap.setProperty("vcap.application.uris", "boot-example.boot-apps.apps.cloud.net");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.name", "jblum-pcc");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.tags", "pivotal,cloudcache,database,gemfire");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users", "admin, root, majorTom, jimbo, buster");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].username", "admin");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].roles", "cluster_admin");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].password", "p@55w0rd");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[1].username", "root");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[1].roles", "cluster_operator");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[1].password", "p@55w0rd");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[2].username", "majorTom");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[2].roles", "cluster_operator,ground_controller");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[2].password", "s3cUr3");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[3].username", "jimbo");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[3].roles", "cluster_fuck");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[3].password", "p@55!t");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[4].username", "buster");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[4].roles", "cluster_operator");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[4].password", "p@55!t");
|
||||
|
||||
VcapPropertySource propertySource = VcapPropertySource.from(vcap);
|
||||
|
||||
assertThat(propertySource).isNotNull();
|
||||
|
||||
Service jblumPcc = Service.with("jblum-pcc");
|
||||
Service nonExistingService = Service.with("non-existing-service");
|
||||
|
||||
Optional<User> user = propertySource.findUserByName(jblumPcc, "majorTom");
|
||||
|
||||
assertThat(user).isNotNull();
|
||||
assertThat(user.map(User::getName).orElse(null)).isEqualTo("majorTom");
|
||||
assertThat(user.flatMap(User::getPassword).orElse(null)).isEqualTo("s3cUr3");
|
||||
|
||||
user = propertySource.findUserByName(jblumPcc, "admin");
|
||||
|
||||
assertThat(user).isNotNull();
|
||||
assertThat(user.map(User::getName).orElse(null)).isEqualTo("admin");
|
||||
assertThat(user.flatMap(User::getPassword).orElse(null)).isEqualTo("p@55w0rd");
|
||||
|
||||
user = propertySource.findUserByName(jblumPcc, "nonExistingUser");
|
||||
|
||||
assertThat(user).isNotNull();
|
||||
assertThat(user.isPresent()).isFalse();
|
||||
|
||||
user = propertySource.findUserByName(nonExistingService, "root");
|
||||
|
||||
assertThat(user).isNotNull();
|
||||
assertThat(user.isPresent()).isFalse();
|
||||
|
||||
|
||||
user = propertySource.findUserByName(jblumPcc, "buster");
|
||||
|
||||
assertThat(user).isNotNull();
|
||||
assertThat(user.map(User::getName).orElse(null)).isEqualTo("buster");
|
||||
assertThat(user.flatMap(User::getPassword).orElse(null)).isEqualTo("p@55!t");
|
||||
}
|
||||
|
||||
private void testFindUserByInvalidNameThrowsIllegalArgumentException(String targetUsername) {
|
||||
|
||||
Properties vcap = new Properties();
|
||||
|
||||
vcap.setProperty("vcap.application.name", "boot-example");
|
||||
vcap.setProperty("vcap.application.uris", "boot-example.boot-apps.apps.cloud.net");
|
||||
|
||||
VcapPropertySource propertySource = VcapPropertySource.from(vcap);
|
||||
|
||||
assertThat(propertySource).isNotNull();
|
||||
|
||||
try {
|
||||
propertySource.findUserByName(Service.with("test-service"), targetUsername);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Target username [%s] is required", targetUsername);
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void findUserByBlankName() {
|
||||
testFindUserByInvalidNameThrowsIllegalArgumentException(" ");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void findUserByEmptyName() {
|
||||
testFindUserByInvalidNameThrowsIllegalArgumentException("");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void findUserByNullName() {
|
||||
testFindUserByInvalidNameThrowsIllegalArgumentException(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findFirstUserByRoleClusterOperatorReturnsOptionalOfUser() {
|
||||
|
||||
Properties vcap = new Properties();
|
||||
|
||||
vcap.setProperty("vcap.application.name", "boot-example");
|
||||
vcap.setProperty("vcap.application.space_name", "outerspace");
|
||||
vcap.setProperty("vcap.application.uris", "boot-example.boot-apps.apps.cloud.net");
|
||||
vcap.setProperty("vcap.services.test-pcc.name", "test-pcc");
|
||||
vcap.setProperty("vcap.services.test-pcc.tags", "pivotal,cloudcache , database, gemfire ");
|
||||
vcap.setProperty("vcap.services.test-pcc.credentials.users", "jdoe");
|
||||
vcap.setProperty("vcap.services.test-pcc.credentials.users[0].username", "jdoe");
|
||||
vcap.setProperty("vcap.services.test-pcc.credentials.users[0].roles", "developer,poweruser,seaswab");
|
||||
vcap.setProperty("vcap.services.test-pcc.credentials.users[0].password", "test");
|
||||
vcap.setProperty("vcap.services.test-pcc.tags", "pivotal,cloudcache , database, gemfire ");
|
||||
vcap.setProperty("vcap.application.space_name", "outerspace");
|
||||
vcap.setProperty("vcap.services.a-pcc.name", "a-pcc");
|
||||
vcap.setProperty("vcap.services.a-pcc.tags", "pivotal,cloudcache,database");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users", "admin, root");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users[0].username", "admin");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users[0].roles", "cluster_admin");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users[0].password", "p@55w0rd");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users[1].username", "root");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users[1].roles", "cluster_operator");
|
||||
vcap.setProperty("vcap.services.a-pcc.credentials.users[1].password", "p@55w0rd");
|
||||
vcap.setProperty("vcap.services.a-pcc.tags", "pivotal,cloudcache,database");
|
||||
vcap.setProperty("vcap.application.uris", "boot-example.boot-apps.apps.cloud.net");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.name", "jblum-pcc");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.tags", "pivotal,gemfire,database");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users", "majorTom, jimbo, buster");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].username", "majorTom");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].roles", "cluster_operator,ground_contoller");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].roles", "cluster_operator,ground_controller");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[0].password", "s3cUr3");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[1].username", "jimbo");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[1].roles", "cluster_fuck");
|
||||
@@ -639,12 +751,13 @@ public class VcapPropertySourceUnitTests {
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[2].username", "buster");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[2].roles", "cluster_operator");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.credentials.users[2].password", "p@55!t");
|
||||
vcap.setProperty("vcap.services.jblum-pcc.tags", "pivotal,gemfire,database");
|
||||
|
||||
VcapPropertySource propertySource = VcapPropertySource.from(vcap);
|
||||
|
||||
assertThat(propertySource).isNotNull();
|
||||
assertThat(propertySource.findFirstUserByRoleClusterOperator(Service.with("test-pcc")).isPresent()).isFalse();
|
||||
assertThat(propertySource.findFirstUserByRoleClusterOperator(Service.with("non-existing-service")).isPresent())
|
||||
.isFalse();
|
||||
|
||||
User root = propertySource.findFirstUserByRoleClusterOperator(Service.with("a-pcc")).orElse(null);
|
||||
|
||||
@@ -667,7 +780,7 @@ public class VcapPropertySourceUnitTests {
|
||||
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.setProperty("vcap.application.name", "withVcapServicePredicateConfiguresVcapServicePredicateReturnsThis");
|
||||
properties.setProperty("vcap.application.name", "withMockVcapServicePredicateConfiguresVcapServicePredicateReturnsThis");
|
||||
properties.setProperty("vcap.application.uris", "{}");
|
||||
|
||||
Predicate<String> mockVcapServicePredicate = mock(Predicate.class);
|
||||
|
||||
Reference in New Issue
Block a user