Fabian Fabian - 6 months ago 98
Java Question

Spring Cloud Config Pattern Matching Not Working With SVN

I'm having issues defining multiple svn based configuration repositories for my Spring Cloud Config Server. I have set up three config repositories. One for development, unit, and production. I've set the default to development (by setting spring.cloud.config.server.svn.uri = development repo uri). But, whenever I make GET requests to the Config Server's REST endpoints, I ALWAYS get the development config no matter which profile I request. See example below...

ex:



curl -i -X GET \
-H "Content-Type:application/json" \
'http://localhost:8888/my-service-accounts/unit'


results in:



{
"name":"my-service-accounts",
"profiles":[
"unit"
],
"label":null,
"version":"750",
"propertySources":[
{
"name":"http://PATH_TO_MY_SVN_SERVER/config-repo-development/trunk/my-service-accounts.yml",
"source":{
"server.port":8080,
"hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds":3000
}
}
]
}


but I expected ...



{
"name":"my-service-accounts",
"profiles":[
"unit"
],
"label":null,
"version":"750",
"propertySources":[
{
"name":"http://PATH_TO_MY_SVN_SERVER/config-repo-unit/trunk/my-service-accounts.yml",
"source":{
"server.port":7777,
"hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds":3000
}
}
]
}



  • note the difference in the propertySources[0].name value. I expect this configuration to come from the unit repository but it's still coming from the development repository.






My Config Server Configuration:



application.yml



server:
port: 8888
spring:
profiles:
include: subversion
cloud:
config:
server:
svn:
username: configserver
password: ************
uri: http://PATH_TO_MY_SVN_SERVER/config-repo-development
repos:
development:
pattern: ["*/development"]
uri: http://PATH_TO_MY_SVN_SERVER/config-repo-development
unit:
pattern: ["*/unit"]
uri: http://PATH_TO_MY_SVN_SERVER/config-repo-unit
production:
pattern:
- '*/production'
uri: http://PATH_TO_MY_SVN_SERVER/config-repo-production

discovery:
enabled: true
application:
name: my-server-config



  • Note: my IDE (IntelliJ) is warning me that it cannot resolve the configuration property for spring.cloud.config.server.svn.repos.*.uri ... but this is how the Spring Cloud Config documentation shows how to specify the repository path.



build.gradle



buildscript {
ext {
springBootVersion = "1.3.3.RELEASE"
}
repositories {
mavenCentral()
maven {url "https://plugins.gradle.org/m2/"}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.spring.gradle:dependency-management-plugin:0.5.5.RELEASE")
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.1.1"
}
}

apply plugin: "base"
apply plugin: "maven"
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'

jar {
baseName = project.ext.projectName
version = project.ext.projectVersion
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
mavenLocal()
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.RC1"
}
}

dependencies {
compile("org.springframework.cloud:spring-cloud-starter-config")
compile("org.springframework.cloud:spring-cloud-config-server")
compile("org.springframework.cloud:spring-cloud-starter-eureka")
compile("org.tmatesoft.svnkit:svnkit")

testCompile("org.springframework.boot:spring-boot-starter-test")
}

eclipse {
classpath {
containers.remove("org.eclipse.jdt.launching.JRE_CONTAINER")
containers "org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"
}
}

task wrapper(type: Wrapper) {
gradleVersion = "2.12"
}

Answer

I ended up reorganizing the directory layout of my svn config repository and using the more flexible "searchPaths" property in order to achieve my desired functionality.

New SVN Repo Layout:

  • /svn/config/trunk/dev/service-name.yml
  • /svn/config/trunk/prod/service-name.yml
  • /svn/config/trunk/unit/service-name.yml

Basically with this approach you define the configuration repository URI and then define a searchPaths property that does pattern matching on the incoming path to determine which directory to search for configuration.

New application.yml

server:
  port: 8888
spring:
  profiles:
    include: subversion
  cloud:
    config:
      server:
        svn:
          username: configserver
          password: ************
          uri: http://PATH_TO_MY_SVN_SERVER/svn/config
          searchPaths: ["{profile}"]
      discovery:
        enabled: true
  application:
    name: my-server-config

Access Config Server via HTTP Endpoint:

curl -i -X GET \
   -H "Content-Type:application/json" \
 'http://localhost:8888/my-service-name/unit'

The config server by default seems to match

svn_server/{application-name}/{pattern_defined_in_searchPaths}

Which in my case is :

svn_server/{application-name}/{profile}