web-dev-qa-db-ja.com

Scala

Scalaでプロジェクトをセットアップする良い方法は何ですか?環境に応じて異なる構成を使用します。

developmenttestおよびproduction環境用に異なるデータベースを特別に用意する必要があります(Railsで行われるものと同様)

24
Daniel Cukier

私が使用しているもう1つの戦略は、 includes を使用することです。私は通常、DEV設定を defaultapplication.confファイルに保存してから、他の環境用の新しいconfファイルを作成し、デフォルトのファイルを含めます。

私のDEV conf application.confが次のようになっているとしましょう:

myapp {
    server-address = "localhost"
    server-port = 9000

    some-other-setting = "cool !"
}

次に、PRODの場合、prod.confという別のファイルを作成できます。

include "application"

# override default (DEV) settings
myapp {
    server-address = ${PROD_SERVER_HOSTNAME}
    server-port = ${PROD_SERVER_PORT}
}

PROD環境で変更される設定のみをオーバーライドすることに注意してください(つまり、some-other-settingはDEVと同じです)。

構成bootstrapコードは何もテストしません

...
val conf = ConfigFactory.load()
...

DEVからPROD confに切り替えるには、システムプロパティをロードする設定ファイルの名前で渡すだけです。

Java -Dconfig.resource=prod.conf ...

DEVでは、application.confdefault によってロードされるため、渡す必要はありません。

したがって、ここでは Typesafe Config のデフォルトのロードメカニズムを使用してこれを実現しています。

この手法を説明するために、単純な project を作成しました。自由に複製して実験してください。

53
ozeebee

タイプセーフな構成を使用します。次のようなConfigオブジェクトを作成します。

import com.typesafe.config._

object Config {
  val env = if (System.getenv("SCALA_ENV") == null) "development" else System.getenv("SCALA_ENV")

  val conf = ConfigFactory.load()
  def apply() = conf.getConfig(env)
}

次に、application.confファイルsrc/main/resourcesフォルダ:

development {
  your_app {
    databaseUrl = "jdbc:mysql://localhost:3306/dev_db"
    databaseUser = "xxxx"
    databasePassword = "xxxx"
  }
}
test {
  your_app {
    databaseUrl = "jdbc:mysql://localhost:3306/test_db"
    databaseUser = "xxxxx"
    databasePassword = "xxxx"
  }
}

これで、アプリケーションのどこからでも、構成にアクセスできます。

Config()。getString( "your_app.databaseUrl")

環境を設定している場合(例:export SCALA_ENV=test)アプリケーションを実行すると、正しい構成セクションが考慮されます。デフォルトは開発です

25
Daniel Cukier

Daniel Cukiersソリューションがデフォルトとオーバーライドを許可しない方法に満足していなかったので、それらを完全に使用するように変更しました。

あなたがしなければならない唯一の設定は、システムで環境変数を設定することです(何も設定されていない場合、デフォルトは 'dev'です)

(Javaソリューション、Scalaと互換性あり):

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

public class MyCompanyConfig {
    public final static Config base = ConfigFactory.load().getConfig("mycompany");
    public final static String environment = System.getenv("ENVIRONMENT") == null ? "dev" : System.getenv("ENVIRONMENT");

    /**
     * Returns a subtree of the base configuration with environment settings applied.
     *
     * @param setting The subtree to return config for.
     * @return A config with base in given setting, with environment modifications applied.
     */
    public static Config load(String setting) {

        Config config = base.getConfig(setting);

        if (config.hasPath(environment)) {
            return config.getConfig(environment).withFallback(config);
        }

        return config;
    }
}

これにより、次のようなライブラリ内の単一のreference.confが許可されます。

mycompany.module1 {
    setting1 : "adefaultvalue"
    url : "localhost"

    test {
        // will be used where ENVIRONMENT="test"
        url : "test.mycompany.com"
    }

    prod {
        // will be used where ENVIRONMENT="prod"
        setting1 : "changethedefault"
        url : "www.mycompany.com"
    }
}

使用法:

Config conf = MyCompanyConfig.load("module1")
2
DHa

以下は、Scalaにあり、オーバーライドが可能で、外部ライブラリに依存しないソリューションです。

_object Config {

  var test: Map[String, String] = {
    Map(
      "libsvmData" -> new Java.io.File("./src/test/resources/sample_libsvm_data.txt").getCanonicalPath,
      "somethingElse" -> "hi"
    )
  }

  var production: Map[String, String] = {
    Map(
      "libsvmData" -> "s3a://my-cool-bucket/fun-data/libsvm.txt",
      "somethingElse" -> "whatever"
    )
  }

  var environment = sys.env.getOrElse("PROJECT_ENV", "production")

  def get(key: String): String = {
    if (environment == "test") {
      test(key)
    } else {
      production(key)
    }
  }

}
_

_PROJECT_ENV_がtestに設定されている場合、Config.get("somethingElse")は_"hi"_を返します。それ以外の場合は、_"whatever"_を返します。

_PROJECT_ENV=test sbt test_を実行すると速く古くなるため、テストスイートの実行時にSBTに環境変数を設定させることができます。

_fork in Test := true
envVars in Test := Map("PROJECT_ENV" -> "test")
_

以下は既存の設定を上書きする方法です。

_Config.test = Config.test ++ Map("somethingElse" -> "give me clean air")
_

これは このトピックについて書いたブログ投稿へのリンクです

0
Powers