Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[#1461] Alternative application.conf file (with system property) #480

Closed
wants to merge 2 commits into from

3 participants

@Neoh59

No description provided.

@mbknor
Collaborator

I am pretty sure that the application.conf file is also read by the python-code..

You have to modify that also.

I also think that the test is to verbose.. too many files.. It would be better to add it to tests.py. (look for the file).

But are this functionality needed? can't you just use the include-functionality and include the file needed?

I think you can even use groovy code/tag syntax to dynamic resolve what to include.

Also make sure you do this against master branch since we only add bugfixes to 1.2.x.

@Neoh59

Sorry for the test but I do it with my poor skills. Create an app with "play new" and just custom the index page to display a special application.conf property.
I read the test.py file but I don't understand how it works, what it does, what to do with it.

Is this functionality needed ? I anwsered in the Lighthouse ticket.

For the branch, I followed the contributor guide (as good as I can). What is wrong ?

@mbknor
Collaborator

no problem.

tests.py is a python program that is scripting play commands and checks the output.
You should write the test in that file since you have to check python stuff also.

Ie: debug-port is read from application.conf file directly from python before play java is started.

The port is written to stdout.. your test should assert that the post chosen is from the external file. if it is, you know that laso python is using the external file.

branch info:

master branch is going to be version 1.3 in the future.. here we add new features like your feature.
1.2.x-branch is coing to be 1.2.5 - we only add bugfixes here.

Your pull request is against the master-branch so that is ok.

@Neoh59

Hi Morten,

I removed the sample app for the test.
And I try to implement a test in test.py for this feature :

  • IF run the app without parameters THEN listening port is 9000 (default port)
  • IF run the app with the parameter THEN listening port is 9876 (port in external-conf-file.conf file)

I confess that I made some uglies copy/paste and I'm not fluent with python.
More, I'm not able to run the test.py file (even with the official master branch)
It seems because I'm on Windows -> WindowsError: [Error 193] %1 is not a valid Win32 application
Is the test OK for you ? Or have you an advice to run tests on Windows ?

@mbknor
Collaborator

Your pullrequest does still not have any code related to the fact that also the python code reads the application.conf file.

Here are all the files using this file in python code:

pym/play/application.py: assert os.path.exists(os.path.join(self.path, 'conf', 'application.conf'))
pym/play/application.py: self.entries = self.readFile(confFolder, "application.conf")
pym/play/commands/ant.py: is_application = os.path.exists(os.path.join(app.path, 'conf', 'application.conf'))
pym/play/commands/base.py: replaceAll(os.path.join(app.path, 'conf/application.conf'), r'%APPLICATION_NAME%', application_name)
pym/play/commands/base.py: replaceAll(os.path.join(app.path, 'conf/application.conf'), r'%SECRET_KEY%', secretKey())
pym/play/commands/eclipse.py: is_application = os.path.exists(os.path.join(app.path, 'conf', 'application.conf'))
pym/play/commands/eclipse.py: # if this is an application, the name of the project is in the application.conf file
pym/play/commands/modulesrepo.py: print "~ Start using it by adding this line in the application.conf modules list: "
pym/play/commands/modulesrepo.py: appConf = os.path.join(app.path, 'conf/application.conf')
pym/play/commands/secret.py: replaceAll(os.path.join(app.path, 'conf', 'application.conf'), r'application.secret=.*', 'application.secret=%s' % sk, True)

@itsadok

@mbknor I don't mean to hijack this thread, but can you give me a pointer regarding the groovy tag for dynamic inclusion? http://stackoverflow.com/questions/9805462

@Neoh59

@mbknor : I think I understand what you want. But for me, it's not what is useful with this feature.
Like opensource21 said in the ticket : the person who runs the software can decide where to put the conf-file
It's useful to add the system property when running the application ("play run" or application server if war).
But I don't think it can be useful in other cases (for example eclipsify, create new application, add module, ...). When you develop an application there is no need to have the file in a special path IMHO so the default behaviour (conf folder) is ok.
More it can limit the impact of changes for this feature.

Perhaps I've not well explained what I think about this feature in the ticket.

PS: If someone uses this feature and want to add it to all Play commands for developments purposes he could be able to do. ;-)

@itsadok

FWIW, the @include functionality doesn't work with python either, and the ${..} functionality also seems very minimal. So this will be just another inconsistency.

@mbknor
Collaborator

See updated ticket. I think this is better solved using a module

@mbknor mbknor closed this
@Neoh59

Yes you're right. I'm too busy for the moment to test it (and if needed improve this module) but it's a better way (because no impact on the core framework).

@fehmicansaglam fehmicansaglam referenced this pull request from a commit in fehmicansaglam/play
@pepite pepite [#480] 325dfe3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 10, 2012
  1. @Neoh59
Commits on Mar 14, 2012
  1. @Neoh59
This page is out of date. Refresh to see the latest.
View
10 documentation/manual/production.textile
@@ -6,6 +6,16 @@ h2. <a name="application">application.conf</a>
First off, the best way to specify production mode is to give a specific ID to your production framework. Let’s pick @production@ as an example. Refer "manage application.conf in several environments":ids to see how.
+h3. Specifying an alternative configuration file
+
+To force a different @application.conf@ file you can use the @config.file@ system property.
+
+bc. play run -Dconfig.file=/etc/play/config/external-conf-file.conf
+
+These system property specify a replacement for the default @conf/application.conf@ file, not an addition.
+
+NB: Note that if you use the <code>@include</code> feature in your application.conf file, remember that they are loaded from the relative path of your @application.conf@ file.
+
h3. Set the framework in prod mode:
bc. %production.application.mode=prod
View
4 framework/src/play/Play.java
@@ -363,7 +363,9 @@ private static Properties readOneConfigurationFile(String filename, Set<String>
Properties propsFromFile=null;
VirtualFile appRoot = VirtualFile.open(applicationPath);
- conf = appRoot.child("conf/" + filename);
+ conf = VirtualFile.open(System.getProperty("config.file", applicationPath + "/conf/" + filename));
+ Logger.info("Load application config file : %s", conf.getRealFile().getAbsolutePath());
+
try {
propsFromFile = IO.readUtf8Properties(conf.inputstream());
} catch (RuntimeException e) {
View
217 samples-and-tests/external-conf-file.conf
@@ -0,0 +1,217 @@
+# This is the main configuration file for the application.
+# ~~~~~
+application.name=external-conf-file
+
+# Application mode
+# ~~~~~
+# Set to dev to enable instant reloading and other development help.
+# Otherwise set to prod.
+application.mode=dev
+%prod.application.mode=prod
+
+# Secret key
+# ~~~~~
+# The secret key is used to secure cryptographics functions
+# If you deploy your application to several instances be sure to use the same key !
+application.secret=J0QCjINUPKguFSYHgK1KSXAbdAcJM6lFa1KXuBQvmO0U8tQvLtNRJm65zQXTWF4Q
+
+# i18n
+# ~~~~~
+# Define locales used by your application.
+# You can then place localized messages in conf/messages.{locale} files
+# application.langs=fr,en,ja
+
+# Date format
+# ~~~~~
+date.format=yyyy-MM-dd
+# date.format.fr=dd/MM/yyyy
+
+# Server configuration
+# ~~~~~
+# If you need to change the HTTP port, uncomment this (default is set to 9000)
+http.port=9876
+#
+# By default the server listen for HTTP on the wilcard address.
+# You can restrict this.
+# http.address=127.0.0.1
+#
+# Use this if you don't host your Play application at the root of the domain
+# you're serving it from. This parameter has no effect when deployed as a
+# war, because the path will be handled by the application server.
+# http.path=/
+
+# Session configuration
+# ~~~~~~~~~~~~~~~~~~~~~~
+# By default, session will be written to the transient PLAY_SESSION cookie.
+# The cookies are not secured by default, only set it to true
+# if you're serving your pages through https.
+# application.session.cookie=PLAY
+# application.session.maxAge=1h
+# application.session.secure=false
+
+# Session/Cookie sharing between subdomain
+# ~~~~~~~~~~~~~~~~~~~~~~
+# By default a cookie is only valid for a specific domain. By setting
+# application.defaultCookieDomain to '.example.com', the cookies
+# will be valid for all domains ending with '.example.com', ie:
+# foo.example.com and bar.example.com
+# application.defaultCookieDomain=.example.com
+
+# JVM configuration
+# ~~~~~
+# Define which port is used by JPDA when application is in debug mode (default is set to 8000)
+# jpda.port=8000
+#
+# Java source level => 1.5, 1.6 or 1.7 (experimental)
+# java.source=1.5
+
+# Log level
+# ~~~~~
+# Specify log level for your application.
+# If you want a very customized log, create a log4j.properties file in the conf directory
+# application.log=INFO
+#
+# More logging configuration
+# application.log.path=/log4j.properties
+# application.log.system.out=off
+
+# Database configuration
+# ~~~~~
+# Enable a database engine if needed.
+#
+# To quickly set up a development database, use either:
+# - mem : for a transient in memory database (H2 in memory)
+# - fs : for a simple file written database (H2 file stored)
+# db=mem
+#
+# To connect to a local MySQL5 database, use:
+# db=mysql://user:pwd@host/database
+#
+# To connect to a local PostgreSQL9 database, use:
+# db=postgres://user:pwd@host/database
+#
+# If you need a full JDBC configuration use the following :
+# db.url=jdbc:postgresql:database_name
+# db.driver=org.postgresql.Driver
+# db.user=root
+# db.pass=secret
+#
+# Connections pool configuration :
+# db.pool.timeout=1000
+# db.pool.maxSize=30
+# db.pool.minSize=10
+#
+# If you want to reuse an existing Datasource from your application server, use:
+# db=java:/comp/env/jdbc/myDatasource
+#
+# When using an existing Datasource, it's sometimes needed to destroy it when
+# the application is stopped. Depending on the datasource, you can define a
+# generic "destroy" method :
+# db.destroyMethod=close
+
+# JPA Configuration (Hibernate)
+# ~~~~~
+#
+# Specify the custom JPA dialect to use here (default to guess):
+# jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
+#
+# Specify the ddl generation pattern to use. Set to none to disable it
+# (default to update in DEV mode, and none in PROD mode):
+# jpa.ddl=update
+#
+# Debug SQL statements (logged using DEBUG level):
+# jpa.debugSQL=true
+#
+# You can even specify additional hibernate properties here:
+# hibernate.use_sql_comments=true
+# ...
+#
+# Store path for Blob content
+attachments.path=data/attachments
+
+# Memcached configuration
+# ~~~~~
+# Enable memcached if needed. Otherwise a local cache is used.
+# memcached=enabled
+#
+# Specify memcached host (default to 127.0.0.1:11211)
+# memcached.host=127.0.0.1:11211
+#
+# Or you can specify multiple host to build a distributed cache
+# memcached.1.host=127.0.0.1:11211
+# memcached.2.host=127.0.0.1:11212
+#
+# Use plain SASL to authenticate for memcached
+# memcached.user=
+# memcached.password=
+
+# HTTP Response headers control for static files
+# ~~~~~
+# Set the default max-age, telling the user's browser how long it should cache the page.
+# Default is 3600 (one hour). Set it to 0 to send no-cache.
+# This is only read in prod mode, in dev mode the cache is disabled.
+# http.cacheControl=3600
+
+# If enabled, Play will generate entity tags automatically and send a 304 when needed.
+# Default is true, set it to false to deactivate use of entity tags.
+# http.useETag=true
+
+# Custom mime types
+# mimetype.xpi=application/x-xpinstall
+
+# WS configuration
+# ~~~~~
+# Default engine is Async Http Client, uncomment to use
+# the JDK's internal implementation
+# webservice = urlfetch
+# If you need to set proxy params for WS requests
+# http.proxyHost = localhost
+# http.proxyPort = 3128
+# http.proxyUser = jojo
+# http.proxyPassword = jojo
+
+# Mail configuration
+# ~~~~~
+# Default is to use a mock Mailer
+mail.smtp=mock
+
+# Or, specify mail host configuration
+# mail.smtp.host=127.0.0.1
+# mail.smtp.user=admin
+# mail.smtp.pass=
+# mail.smtp.channel=ssl
+
+# Url-resolving in Jobs
+# ~~~~~~
+# When rendering templates with reverse-url-resoling (@@{..}) in Jobs (which do not have an inbound Http.Request),
+# ie if sending a HtmlMail, Play need to know which url your users use when accessing your app.
+# %test.application.baseUrl=http://localhost:9000/
+# %prod.application.baseUrl=http://www.yourdomain.com/
+
+# Jobs executor
+# ~~~~~~
+# Size of the Jobs pool
+# play.jobs.pool=10
+
+# Execution pool
+# ~~~~~
+# Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.
+# Try to keep a low as possible. 1 thread will serialize all requests (very useful for debugging purpose)
+# play.pool=3
+
+# Open file from errors pages
+# ~~~~~
+# If your text editor supports opening files by URL, Play! will
+# dynamically link error pages to files
+#
+# Example, for textmate:
+# play.editor=txmt://open?url=file://%s&line=%s
+
+# Testing. Set up a custom configuration for test mode
+# ~~~~~
+#%test.module.cobertura=${play.path}/modules/cobertura
+%test.application.mode=dev
+%test.db.url=jdbc:h2:mem:play;MODE=MYSQL;LOCK_MODE=0
+%test.jpa.ddl=create
+%test.mail.smtp=mock
+
View
44 samples-and-tests/i-am-a-developer/tests.py
@@ -628,6 +628,50 @@ def testSimpleProjectCreation(self):
killPlay()
self.play.wait()
+ def testExternalConfFile(self):
+
+ # Well
+ step('Hello, I need an external application.conf file')
+
+ self.working_directory = bootstrapWorkingDirectory('i-need-an-external-conf-file')
+
+ # play new yop
+ step('Create a new project')
+
+ self.play = callPlay(self, ['new', '%s/externalconffile' % self.working_directory, '--name=EXTCONF'])
+ self.assert_(waitFor(self.play, 'The new application will be created'))
+ self.assert_(waitFor(self.play, 'OK, the application is created'))
+ self.assert_(waitFor(self.play, 'Have fun!'))
+ self.play.wait()
+
+ self.assert_(os.path.exists(os.path.join(self.working_directory, 'externalconffile')))
+ self.assert_(os.path.exists(os.path.join(self.working_directory, 'externalconffile/conf')))
+ self.assert_(os.path.exists(os.path.join(self.working_directory, 'externalconffile/conf/application.conf')))
+
+ app = '%s/externalconffile' % self.working_directory
+
+ # Run the newly created application
+ step('Run the newly created application')
+
+ self.play = callPlay(self, ['run', app])
+ self.assert_(waitFor(self.play, 'Listening for HTTP on port 9000'))
+
+ step("stop play")
+ killPlay()
+ self.play.wait()
+
+ # Run the newly created application
+ step('Run the newly created application with external application.conf file')
+
+ self.play = callPlay(self, ['run', app, '-Dconfig.file=%s/../external-conf-file.conf' % self.working_directory])
+ self.assert_(waitFor(self.play, 'Listening for HTTP on port 9876'))
+
+ step("stop play")
+ killPlay()
+ self.play.wait()
+
+ step("done testing external application.conf file")
+
def tearDown(self):
killPlay()
Something went wrong with that request. Please try again.