14

Was ist eine gute Möglichkeit, ein Projekt in Scala einzurichten, die je nach Umgebung unterschiedliche Konfigurationen verwendet.spezifische Konfiguration von Umgebung in Scala

Ich brauche speziell verschiedene Datenbanken für Entwicklung, Test und Produktion Umgebung (ähnlich dem, was geschieht in Rails)

Antwort

16

Verwenden Config typsichere müssen. Erstellen Sie eine Config-Objekt wie folgt aus:

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) 
} 

dann die application.conf Datei in src/main/resources Ordner erstellen:

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" 
    } 
} 

Jetzt von überall in Ihrer Anwendung, können Sie Zugriff auf Konfiguration:

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

Wenn Sie Ihre Umgebung eingerichtet haben (z. B. export SCALA_ENV=test), wenn Sie Sie ausführen Bei der Anwendung wird der richtige Konfigurationsabschnitt berücksichtigt. Der Standard ist Entwicklung

+0

Es dauerte eine Weile, bis ich dieses Muster gefunden habe, das den Vorrang der Systemeigenschaften behält: ConfigFactory.defaultOverrides(). WithFallback (config2.getConfig (environment)). WithFallback (config2); https://github.com/typesafehub/config/blob/master/examples/java/complex-app/src/main/java/ComplexApp.java –

28

Eine andere Strategie, die ich verwende besteht aus includes. Normalerweise speicher ich meine DEV-Einstellungen in der defaultapplication.conf Datei, dann erstelle ich eine neue Conf-Datei für andere Umgebungen und die Standard-eine.

Lassen Sie uns meine DEV conf sagen application.conf wie folgt aussieht:

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

    some-other-setting = "cool !" 
} 

dann für die ART, konnte ich eine andere Datei prod.conf genannt haben:

include "application" 

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

Bitte beachte, dass ich die Einstellungen nur außer Kraft setzen diese Änderung in der PROD-Umgebung (some-other-setting ist also die gleiche wie in DEV).

Der Code Config-Bootstrap-Test nichts

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

von der DEV auf den ART conf zu wechseln, einfach eine Systemeigenschaft mit dem Namen der Konfigurationsdatei zu laden passieren:

java -Dconfig.resource=prod.conf ... 

In DEV, keine Notwendigkeit, es zu übergeben, da application.conf von default geladen wird.

Also hier verwenden wir Typesafe Config Standard-Lademechanismus, um dies zu erreichen.

Ich habe eine einfache project erstellt, um diese Technik zu demonstrieren. Fühlen Sie sich frei zu klonen und zu experimentieren.

+0

Der Vollständigkeit halber glaube ich, dass der Config Bootstrap wäre: val conf = ConfigFactory. load() def Anwenden() = conf.getConfig ("myapp") – mmeyer

+0

@ozeebee aus irgendeinem Grund funktioniert das nicht. Beachten Sie, dass ich hinzugefügt habe: 'fork in run: = true' und' java -Dconfig.resource = stg.conf' in build.sbt. Datei stg.conf ist unter Ressourcen, aber meine Konfiguration kommt immer noch aus der application.conf. Beachten Sie auch, dass wenn ich folgendes benutze: 'val conf = ConfigFactory.load (" stg.conf ")' dann werden meine Konfigurationen per stg.conf geladen. Irgendeine Idee? – has981

+0

@ has981 keine Ahnung. Ich habe ein einfaches [Projekt] (https://github.com/ozeebee/test-scala-config) eingerichtet, um diese Technik zu demonstrieren. Fühlen Sie sich frei zu klonen und zu experimentieren. – ozeebee

1

Ich war nicht glücklich darüber, wie die Lösung von Daniel Cukiers keine Standardeinstellungen und Überschreibungen zuließ, also habe ich sie geändert, um sie voll auszunutzen.

Die einzige Konfiguration, die Sie tun müssen, um eine Umgebungsvariable auf dem System (Standard: 'dev', wenn keine gesetzt) ​​gesetzt

(Java-Lösung, kompatibel mit 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; 
    } 
} 

Dies ermöglicht eine einzelne reference.conf in einer Bibliothek wie folgt aussehen:

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" 
    } 
} 

Verbrauch:

Config conf = MyCompanyConfig.load("module1") 
Verwandte Themen