How to use Environment variables setted on cloudhub in java class - java

In local environment , we can configure some connection Environment properties in a property file, and then use them by context:property-placeholder. for example:
<context:property-placeholder location="classpath:resources-local.properties"/>
<smtp:endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.user}" password="${smtp.password}" name="NotificationEmail" doc:name="SMTP" to="${smtp.to}" from="${smtp.from}" subject="error" />
But when I deploy the app to cloudhub,I can set the connection info as Environment variables.We don't need to import the resources-local.properties file.We can still use the properties as
<smtp:endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.user}" password="${smtp.password}" name="NotificationEmail" doc:name="SMTP" to="${smtp.to}" from="${smtp.from}" subject="error" />
here is the question,how can I use Environment variables setted on cloudhub in java class.How can I get the smtp.host value in java class???
David told me that I can use them as they available as system properties.
But How to use the system properties in java class..
Any advise?? Thanks a lot!

The best option is to inject them into your class via Spring. E.g.:
<bean class="my.java.Object">
<property name="smtp" value="${smtp.host}">
</bean>
However, getting it as a system property via System.getProperty("smtp.host") will also work.

From a java class, just use System.getProperty("smtp.host");

Related

With Open Liberty, how to use an environment variable as an application property?

I expected to be able to do something like this in my server.xml, but I could not get it to work:
<variable name="my.ldap.url" value="${LDAP_URL}" />
Setting it in jvm.options or server.env do not seem to be options either from what I can tell. Neither of those are parsing environment variables from my tests.
-Dmy.ldap.url=$LDAP_URL
Setting properties in my own files and using environment variables did not seem to work either. I tried something like this in my server.xml
<library id="configs">
<fileset dir="${server.config.dir}/configs" includes="*.properties" />
</library>
So I'm just lost for ideas right now. How do I take environment variables and inject them into an Open Liberty application as application properties?
I searched high and low for documentation on this, with no success.
In Jboss I was able to accomplish simple via
bin/standalone.sh -Dmy.ldap.url=$LDAP_URL
It should work for you exactly the way it does in Jboss:
wlp/bin/server start server1 -Dmy.ldap.url=$LDAP_URL
Your <variable> definition would create a Liberty configuration variable that resolves to the value of LDAP_URL in the environment, but it would not be set as a java system property.
If you're still seeing problems with passing the value on the command line you could check all java system properties by running:
wlp/bin/server dump {server name}
In the output zip file, the dump_{timestamp}/introspections/JavaRuntimeInformation.txt will show both the command line arguments and all defined java system properties.
I'd consider using Microprofile config, checkout this guide and see it does answer your questions.
It shows you how to inject variables using following schema:
#Inject #ConfigProperty(name="port")
private int port;
assuming there is PORT env entry in your system.
You can also use env variables in server configuration using server.xml for example:
<properties.db2.jcc serverName="${JDBC_HOST}" portNumber="${JDBC_PORT}" databaseName="${JDBC_DB}" sslConnection="${JDBC_SSL}"
user="${JDBC_ID}" password="${JDBC_PASSWORD}"/>
Details here https://openliberty.io/docs/latest/reference/config/server-configuration-overview.html
For your library point you would have to add it to your application via classloader, so I wouldn't recommend that. Like this:
<application name="myapp" type="ear" location="myapp.ear">
<classloader commonLibraryRef="configs" />
</application>
Hope it solves your problems.
The final answer I found to this, is you can inject environment variables into properties using the <appProperties> tag in your server.xml
Documentation is here
https://openliberty.io/guides/microprofile-config-intro.html#configuring-as-an-appproperties-element-scoped-by-application
A simple example of this using an environment variable looks like ...
<webApplication location="my.war" type="war">
<appProperties>
<property name="my.ldap.url" value="${LDAP_URL}"/>
</appProperties>
</webApplication>

How to correctly add JVM System properties flag

In the Solr logs I see error -
java.lang.UnsupportedOperationException: Serialization support for
org.apache.commons.collections.functors.InvokerTransformer is disabled for
security reasons. To enable it set system property
'org.apache.commons.collections.enableUnsafeSerialization' to 'true',
but you must ensure that your application does not de-serialize
objects from untrusted sources.
I am trying to add flag -Dorg.apache.commons.collections.enableUnsafeSerialization=true, but it don't help.
How to correctly enable this property? (I haven't access to the solrconfig.xml)
You can add it to SOLR_OPTS environment variable or pass it directly to start script:
bin/solr start -Dorg.apache.commons.collections.enableUnsafeSerialization=true
As per Configuring solrconfig.xml docs:
In general, any Java system property that you want to set can be passed through the bin/solr script using the standard -Dproperty=value syntax. Alternatively, you can add common system properties to the SOLR_OPTS environment variable defined in the Solr include file (bin/solr.in.sh or bin/solr.in.cmd).

What's the recommended way to set networkaddress.cache.ttl in Elastic Beanstalk?

I need to set Java's DNS cache TTL (networkaddress.cache.ttl) for an Amazon Elastic Beanstalk app running in Tomcat 8. Because EB can start and stop server instances at any time, I can't simply edit a Tomcat config file and the server and expect the change to persist.
I tried setting the networkaddress.cache.ttl and sun.net.inetaddr.ttl environment variables, but those had no effect. Amazon says calling java.security.Security.setProperty("networkaddress.cache.ttl" , "60"); "will not work if you run your application inside of Tomcat" (http://aws.amazon.com/articles/4035). What's a good way to set the TTL?
The problem is that I was doing it wrong. Setting the sun.net.inetaddr.ttl environment variable works. You can do this in your Elastic Beakstalk config file:
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: sun.net.inetaddr.ttl
value: 60
60 seconds is the value recommended by Amazon
Another option that seems a little nicer to me is to create and use a java.security file:
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: java.security.properties
value: /etc/myapp/java.security
container_commands:
00create_config_dir:
command: 'mkdir -p /etc/myapp'
ignoreErrors: true
01create_java_security_file:
command: 'echo "networkaddress.cache.ttl=60" > /etc/myapp/java.security'
ignoreErrors: true
If you are using spring framework, following is what I did to set the networkaddress.cache.ttl at the time of application initialisation.
Define a new Java class as follows.
package com.example.util;
public class SecurityManager {
public SecurityManager() {
java.security.Security.setProperty("networkaddress.cache.ttl", "60");
}
}
Ask spring framework to instantiate the object of above class as a singleton at the time on spring container creation.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="securityManager"
class="com.example.util.SecurityManager" scope="singleton" />
</beans>
If you are using Spring Boot, you can define a #Configuration
#Configuration
class SecurityManager {
init {
Security.setProperty("networkaddress.cache.ttl", "5")
}
}

Spring to read from my system environment variables

I want to use my system environment variables (i.e use variable FOO that I have defined in my .bash_profile export FOO=BAR) for values in Spring's applicationContext.xml;
For example:
<bean id="dataSource" ...>
<property name="jdbcUrl" value="${FOO}" />
...
</bean>
I use both the Maven-tomcat-plugin and Tomcat inside IntelliJ to run my server.
Right now when my webapp starts up, it can't find the system variables.
What do I have to do to get Spring to read from my system environment variables?
P.S. I have already checked out how to read System environment variable in Spring applicationContext, but doesn't seem to work for me
System environment variables are different to the JVM system properties - which the spring PropertyPlaceholderConfigurer gives you access to. So you'd need to add to the JVM command:
java ... -DFOO=${FOO}
(where -DFOO is defining "FOO" as a JVM system property and ${FOO} is inserting the "BAR" value from your "FOO" environment variable)
See also the ServletContextPropertyPlaceholderConfigurer - with the SYSTEM_PROPERTIES_MODE_OVERRIDE property and a few other options.
try this (Spring Expression Language)
<bean id="dataSource" ...>
<property name="jdbcUrl" value="#{systemEnvironment.FOO}" />
...
</bean>
or add this line
<context:property-placeholder/>
to application context

How to get a tomcat Environment variable in a PropertyPlaceholderConfigurer

I try to get an Environment variable specified in Tomcat's server.xml in a 'PropertyPlaceholderConfigurer' located in my jpa-spring.xml file.
So far, the setup looks as follows:
Tomcat server.xml
<Environment description="Identifies the server environement"
name="server-env"
type="java.lang.String"
value="dev" />
The in WebContent/META-INF/context.xml:
<Context>
<ResourceLink name="server-env" global="server-env" type="java.lang.String"/>
</Context>
Which is referenced in WebContent/WEB-INF/web.xml like:
<resource-env-ref>
<description>Identifies server environement</description>
<resource-env-ref-name>server-env</resource-env-ref-name>
<resource-env-ref-type>java.lang.String</resource-env-ref-type>
</resource-env-ref>
<!-- Spring Integration -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/jpa-spring.xml
</param-value>
</context-param>
And in /WEB-INF/config/jpa-spring.xml I try to get that variable as a replacement:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>WEB-INF/config/db.${server-env}.properties</value>
</list>
</property>
</bean>
This is a setup I put together using information from several articles found on the web.
However, I get an error like ...
Could not resolve placeholder 'server-env' in [WEB-INF/config/db.${server-env}.properties] as system property: neither system property nor environment variable found
05 Nov 2011 14:45:13,385 org.springframework.web.context.ContextLoader
ERROR Context initialization failed
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/config/db.${server-env}.properties]
... when starting tomcat.
What is the right approach to achieve what I am looking for?
I know that this question is similar to this, and this question. However, I even couldn't figure it out with the information from these answers.
Here are my suggestion
With the current set up, its really going to be complicated to read JNDI property server-env and use the same to load the property file.
The way you have assembled the spring application (and PropertyPlaceholderConfigurer), spring will try to look for the property server-env first in OS environment then in java system properties (passed from command using -D option). It finds it at neither of these places and hence fails.
So currently the easiest way out right now is to pass the value of server-env form command prompt of your application server (where you invoke java ; typical syntax would be -Dserver-env=dev). I leave this to you to figure out.
if above option appears a bit complicated, another easier way out is set an environment variable with name server-env to its appropriate values (on Windows its set server-env=dev. Plz check respect OS documentations for this).
Those Environment elements are setting up JNDI. Getting values out of JNDI isn't supported, by default, by any simple syntactic sugar in Spring.
http://www.theserverside.com/news/thread.tss?thread_id=35474#179220
might give you some useful ideas.

Categories