'Cloud datastore dynamic namespace

Requirement
For Cloud, datastore needs to change namespace dynamically. (example store kind as per company Name)

Used Spring cloud DataRepository with Springboot for same

Issue
We need to declare spring.cloud.gcp.datastore.namespace in application.properties which is static. Is there any way to change this dynamically with CRUDReposity of spring cloud

Thanks in advance



Solution 1:[1]

You can change anything you want in your application.properties at runtime using Spring Cloud Config.

Spring Cloud Config provides server-side and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications but can be used with any application running in any language.

Just as a quick example on how you can use this , you should firstly add the dependency : eg gradlecompile group: 'org.springframework.cloud', name: 'spring-cloud-starter', version: '1.1.1.RELEASE', then you need to add the @RefreshScope on the desired configuration bean.

You will be able to view your current config at a certain endpoint, like "applicationConfig: [classpath:/application.properties]": { "my.property": "value1", etc

And then you can change the properties as you wish doing a POST request like :

curl -X POST http://localhost:8080 -d my.property=value2

There is also a nice article about dynamically reloading the properties in a Spring application here. It is nice because they actually display more ways that you can achieve that.

Solution 2:[2]

You can use DatastoreNamespaceProvider which can dynamically return needed namespace.

Was added in this PR PR Also see this discussion here and this recommendation

@Component
@RequiredArgsConstructor
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public class HeaderValueProvider implements Supplier<String>, DatastoreNamespaceProvider {
private final HttpServletRequest httpServletRequest;

 @Override
 public String get() {
    return httpServletRequest.getHeader("someHeader");
 }
}

And this

@Component
public class UserContextProvider implements DatastoreNamespaceProvider, Consumer<UUID> {
private static final ThreadLocal<UUID> USER_CONTEXT = new ThreadLocal<>();

@Override
public String get() {
    return ofNullable(USER_CONTEXT.get())
            .map(UUID::toString)
            .orElse(null);
}

@Override
public void accept(UUID uuid) {
    USER_CONTEXT.set(uuid);
}

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrei Tigau
Solution 2 Brachi