diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java index 79a34643..3638f0b7 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.web.client.RestTemplate; /** * @author Dave Syer @@ -106,7 +107,7 @@ public class EnvironmentRepositoryConfiguration { protected static class VaultConfiguration { @Bean public EnvironmentRepository environmentRepository(HttpServletRequest request, EnvironmentWatch watch) { - return new VaultEnvironmentRepository(request, watch); + return new VaultEnvironmentRepository(request, watch, new RestTemplate()); } } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java index 57b4243f..e7e5290a 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java @@ -61,16 +61,17 @@ public class VaultEnvironmentRepository implements EnvironmentRepository { @NotEmpty private String profileSeparator = ","; - private RestTemplate rest = new RestTemplate(); + private RestTemplate rest; //TODO: move to watchState:String on findOne? private HttpServletRequest request; private EnvironmentWatch watch; - public VaultEnvironmentRepository(HttpServletRequest request, EnvironmentWatch watch) { + public VaultEnvironmentRepository(HttpServletRequest request, EnvironmentWatch watch, RestTemplate rest) { this.request = request; this.watch = watch; + this.rest = rest; } @Override @@ -89,13 +90,15 @@ public class VaultEnvironmentRepository implements EnvironmentRepository { for (String key : keys) { // read raw 'data' key from vault String data = read(key); - // data is in json format of which, yaml is a superset, so parse - final YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); - yaml.setResources(new ByteArrayResource(data.getBytes())); - Properties properties = yaml.getObject(); + if (data != null) { + // data is in json format of which, yaml is a superset, so parse + final YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); + yaml.setResources(new ByteArrayResource(data.getBytes())); + Properties properties = yaml.getObject(); - if (!properties.isEmpty()) { - environment.add(new PropertySource("vault:"+key, properties)); + if (!properties.isEmpty()) { + environment.add(new PropertySource("vault:" + key, properties)); + } } } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java index d213f1b7..a3962d85 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java @@ -1,14 +1,74 @@ package org.springframework.cloud.config.server.environment; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.cloud.config.environment.Environment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.client.RestTemplate; /** * @author Spencer Gibb + * @author Ryan Baxter */ public class VaultEnvironmentRepositoryTests { + + @Before + public void init() {} + @Test - public void testFindOne() { - //TODO: implement testFindOne + public void testFindOne() throws IOException { + MockHttpServletRequest configRequest = new MockHttpServletRequest(); + configRequest.addHeader("X-CONFIG-TOKEN", "mytoken"); + RestTemplate rest = Mockito.mock(RestTemplate.class); + ResponseEntity myAppResp = Mockito.mock(ResponseEntity.class); + Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK); + VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class); + Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}"); + Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp); + Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"), + Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class), + Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp); + ResponseEntity appResp = Mockito.mock(ResponseEntity.class); + Mockito.when(appResp.getStatusCode()).thenReturn(HttpStatus.OK); + VaultEnvironmentRepository.VaultResponse appVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class); + Mockito.when(appVaultResp.getData()).thenReturn(null); + Mockito.when(appResp.getBody()).thenReturn(appVaultResp); + Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"), + Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class), + Mockito.eq("secret"), Mockito.eq("application"))).thenReturn(appResp); + VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest); + Environment e = repo.findOne("myapp", null, null); + assertEquals("myapp", e.getName()); + Map result = new HashMap(); + result.put("foo", "bar"); + assertEquals(result, e.getPropertySources().get(0).getSource()); + } + + @Test(expected = IllegalArgumentException.class) + public void missingConfigToken() throws IOException { + MockHttpServletRequest configRequest = new MockHttpServletRequest(); + RestTemplate rest = Mockito.mock(RestTemplate.class); + ResponseEntity myAppResp = Mockito.mock(ResponseEntity.class); + Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK); + VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class); + Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}"); + Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp); + Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"), + Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class), + Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp); + VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest); + repo.findOne("myapp", null, null); } }