使用typesafe配置解析独立的字符串/文件

时间:2017-03-21 20:38:38

标签: scala config typesafe-config

我正在寻找一种说法:

val c: Config = ConfigFactory.parseString("a=fox,b=dog")
val s: String = """This is a "quick" brown ${a}.\nThat is a lazy, lazy ${b}."""
println(c.resolveString(s))

// Should print:
// > This is a "quick" brown fox.
// > That is a lazy lazy dog.

我的两个想法:

  • 只需找到带有正则表达式的占位符,然后逐个替换配置
  • s转换为具有单一值的配置并使用resolveWith - 但似乎引用可能非常棘手

也许有一种更简单的方法?

2 个答案:

答案 0 :(得分:1)

天真的解决方案:

class Resolver(vars: Config) {
  private lazy val placeholderRegex = "(?<=\\$\\{).*?(?=\\})".r

  def resolveString(s: String): String = {
    placeholderRegex.findAllIn(s).foldLeft(s) { (str, v) =>
      if (vars.hasPath(v)) str.replaceAll("\\Q${" + v + "}\\E", vars.getString(v)) else str
    }
  }

如果字符串不是很大并且没有疯狂数量的不同占位符,那应该没问题。

答案 1 :(得分:0)

我有类似的情况,我之前会自动推送弹性搜索索引定义 我启动了使用这些索引定义的作业。

在我的例子中,包含变量引用的字符串是 JSON索引/模板定义,它也来自typesafe配置。 (参见下面的es.template_or_index.json。)

我使用我在上面写的实用程序方法解析这些引用 apache.commons StrSubstitutor。

(参见:下面的VariableReferenceResolver.resolveReferences(字符串模板))

以下是我的配置示例。请注意该属性&#39; es.animal&#39;被注入到索引/模板json中。 这不能通过类型安全配置库的开箱即用功能来完成(但我想这会 是他们添加的一个很棒的功能!)

 es {
      // user and password credentials should not be checked in to git. deployer is expected to
      // set these parameters into the their environment in whatever way is convenient -- .bashrc or whatever.
      user = dummy
      user = ${?ES_USER}
      password = dummy.passwd
      password = ${?ES_PASSWORD}
      hostPort = "localhost:9200"
      hostPort = ${?ES_HOST_PORT}
      protocol = http
      protocol = ${?ES_PROTOCOL}

      animal = horse            // This gets injected into the configuration property es.template_or_index.json


      // Note: for template json there is a second round of interpolation performed so the json can reference any defined
      // property of this configuration file (or anything it includes)
      template_or_index {
        name = test_template
        json = """
      {
          "template": "${es.animal}_sql-*",
          "settings": {
            "number_of_shards": 50,
            "number_of_replicas": 2
          },
          "mappings": {
                 "test_results" : {
                     "date_detection": false,
                     "properties" : {
                         "timestamp" : { "type" : "date"},
                         "yyyymmdd" : { "type" : "string", "index" : "not_analyzed"}
                     }
                 }
          }
        }
        """
      }
 }



package com.foo

import com.typesafe.config.Config;
import org.apache.commons.lang.text.StrLookup;
import org.apache.commons.lang.text.StrSubstitutor;

public class VariableReferenceResolver {
    final StrSubstitutor substitutor;

    static class ConfigStrLookup extends StrLookup {
          private final Config config;

          ConfigStrLookup(Config config) {
              this.config = config;
          }

          public String lookup(String key) {
              return config.getString(key);
          }
      }

    public VariableReferenceResolver (Config config) {
        substitutor=new StrSubstitutor(new ConfigStrLookup(config));

    }

    public String resolveReferences(String template) {
        return substitutor.replace(template);
    }
}


public class OtherClass { 
    private static void getIndexConfiguration(String path) throws IOException {
        System.setProperty("config.file", path);
        Config config = ConfigFactory.load();
        String user =  config.getString("es.user");
        String password =  config.getString("es.password");
        String protocol =  config.getString("es.protocol");
        String hostPort =  config.getString("es.hostPort");
        String indexOrTemplateJson = config.getString("es.template_or_index.json");
        String indexOrTemplateName = config.getString("es.template_or_index.name");
        VariableReferenceResolver resolver = new VariableReferenceResolver(config);
        String resolvedIndexOrTemplateJson = resolver.resolveReferences(indexOrTemplateJson);

        File jsonFile = File.createTempFile("index-or-template-json", indexOrTemplateName);
        Files.write(Paths.get(jsonFile.getAbsolutePath()), resolvedIndexOrTemplateJson.getBytes());

        curlIndexOrTemplateCreateCommand =
                String.format(
                        "curl  -XPUT  -k -u %s:%s %s://%s/_template/%s -d @%s",
                        user, password, protocol, hostPort, indexOrTemplateName,  jsonFile.getAbsolutePath());
    }


            ....
}