Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple application properties files (incl from classpath) #2187

Merged
merged 2 commits into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ spec:
- java
- -jar
- /opt/feast/feast-serving.jar
- --spring.config.location=
{{- if index .Values "application.yaml" "enabled" -}}
- {{- if index .Values "application.yaml" "enabled" -}}
classpath:/application.yml
{{- end }}
{{- if index .Values "application-generated.yaml" "enabled" -}}
Expand Down
4 changes: 2 additions & 2 deletions infra/docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ services:
- java
- -jar
- /opt/feast/feast-core.jar
- --spring.config.location=classpath:/application.yml,file:/etc/feast/application.yml
- classpath:/application.yml,file:/etc/feast/application.yml

jobservice:
image: gcr.io/kf-feast/feast-jobservice:${FEAST_VERSION}
Expand Down Expand Up @@ -104,7 +104,7 @@ services:
- java
- -jar
- /opt/feast/feast-serving.jar
- --spring.config.location=classpath:/application.yml,file:/etc/feast/application.yml
- classpath:/application.yml,file:/etc/feast/application.yml

redis:
image: redis:5-alpine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class ServingGuiceApplication {
public static void main(String[] args) throws InterruptedException, IOException {
if (args.length == 0) {
throw new RuntimeException(
"Path to application configuration file needs to be specifed via CLI");
"Path to application configuration file needs to be specified via CLI");
}

final Injector i =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
// https://www.baeldung.com/configuration-properties-in-spring-boot
// https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties

import com.fasterxml.jackson.annotation.JsonMerge;
import com.fasterxml.jackson.annotation.OptBoolean;
import feast.common.logging.config.LoggingProperties;
import feast.storage.connectors.redis.retriever.RedisClusterStoreConfig;
import feast.storage.connectors.redis.retriever.RedisStoreConfig;
Expand Down Expand Up @@ -83,6 +85,7 @@ public void setActiveStore(String activeStore) {
/**
* Collection of store configurations. The active store is selected by the "activeStore" field.
*/
@JsonMerge(OptBoolean.FALSE)
private List<Store> stores = new ArrayList<>();

/* Metric tracing properties. */
Expand Down Expand Up @@ -177,6 +180,9 @@ public static class Store {

private Map<String, String> config = new HashMap<>();

// default construct for deserialization
public Store() {}

public Store(String name, String type, Map<String, String> config) {
this.name = name;
this.type = type;
Expand Down Expand Up @@ -210,17 +216,17 @@ public StoreType getType() {
return StoreType.valueOf(this.type);
}

public void setType(String type) {
this.type = type;
}

/**
* Gets the configuration to this specific store. This is a map of strings. These options are
* unique to the store. Please see protos/feast/core/Store.proto for the store specific
* configuration options
*
* @return Returns the store specific configuration
*/
public Map<String, String> getConfig() {
return config;
}

public RedisClusterStoreConfig getRedisClusterConfig() {
return new RedisClusterStoreConfig(
this.config.get("connection_string"),
Expand All @@ -235,6 +241,10 @@ public RedisStoreConfig getRedisConfig() {
Boolean.valueOf(this.config.getOrDefault("ssl", "false")),
this.config.getOrDefault("password", ""));
}

public void setConfig(Map<String, String> config) {
this.config = config;
}
}

public static class Server {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
package feast.serving.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.io.Resources;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class ApplicationPropertiesModule extends AbstractModule {
private final String[] args;
Expand All @@ -36,9 +39,37 @@ public ApplicationPropertiesModule(String[] args) {
public ApplicationProperties provideApplicationProperties() throws IOException {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
mapper.findAndRegisterModules();
ApplicationProperties properties =
mapper.readValue(new File(this.args[0]), ApplicationProperties.class);
mapper.setDefaultMergeable(Boolean.TRUE);

ApplicationProperties properties = new ApplicationProperties();
ObjectReader objectReader = mapper.readerForUpdating(properties);

String[] filePaths = this.args[0].split(",");
for (String filePath : filePaths) {
objectReader.readValue(readPropertiesFile(filePath));
}

return properties;
}

/**
* Read file path in spring compatible format, eg classpath:/application.yml or
* file:/path/application.yml
*/
private byte[] readPropertiesFile(String filePath) throws IOException {
if (filePath.startsWith("classpath:")) {
filePath = filePath.substring("classpath:".length());
if (filePath.startsWith("/")) {
filePath = filePath.substring(1);
}

return Resources.toByteArray(Resources.getResource(filePath));
}

if (filePath.startsWith("file")) {
filePath = filePath.substring("file:".length());
}

return Files.readAllBytes(Path.of(filePath));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package feast.serving.config;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import feast.serving.grpc.OnlineServingGrpcServiceV2;
import io.grpc.Server;
import io.grpc.ServerBuilder;
Expand All @@ -30,7 +31,7 @@ protected void configure() {
bind(OnlineServingGrpcServiceV2.class);
}

// @Provides
@Provides
public Server provideGrpcServer(
ApplicationProperties applicationProperties,
OnlineServingGrpcServiceV2 onlineServingGrpcServiceV2,
Expand Down