How to pass empty string as a command line property to Spring? - spring

FYI: I am using Intellij's 'Run/Debug Configurations' tool.
I would like to pass an empty string as a property to my app via the command line:
--spring.ldap.username=
I have tried:
--spring.ldap.username= # results in parse error
--spring.ldap.username=''
--spring.ldap.username="" # results in parse error
--spring.ldap.username=\"\"
The attempts that actually parsed successfully yielded incorrect values, as demonstrated when I try to print the 'empty' Strings:
System.out.println(environment.getProperty("spring.ldap.username"));
// returns:
// ''
// ""
Setting the same property to an empty string in the application.properties file works perfectly:
spring.ldap.username=
The same print statement:
// returns:
//
// ^^ totally empty string
Is there a trick I am missing?

Try this: --spring.ldap.username (if you leave the =, it will parse as null)

So as it turns out, this can be accomplished by using regular JVM arguments.
Instead of
--my.property=
use
-Dmy.property=
Native JVM arguments are able to accept empty Strings I guess.
In IntelliJ, you can add them in the respective fields in the Run/Debug Configurations window as shown below:
This answer to another question also has some more information on passing JVM arguments to Spring applications.

Related

How to prevent syntax errors when reading BASH associative array values which contain slashes from a child process?

I'm using bash 4.4.19(1)-release.
At the start of my program I read customer configuration values from the command line, configuration file(s), and the environment (in decreasing order of precedence). I validate these configuration values against internal definitions, failing out if required values are missing or if the customer values don't match against accepted regular expressions. This approach is a hard requirement and I'm stuck using BASH for this.
The whole configuration process involves the parsing of several YAML files and takes about a second to complete. I'd like to only have to do this once in order to preserve performance. Upon completion, all of the configured values are placed in a global associative array declared as follows:
declare -gA CONFIG_VALUES
A basic helper function has been written for accessing this array:
# A wrapper for accessing the CONFIG_VALUES array.
function get_config_value {
local key="${1^^}"
local output
output="${CONFIG_VALUES[${key}]}"
echo "$output"
}
This works perfectly fine when all of the commands are run within the same shell. This even works when the get_config_value function is called from a child process. Where this breaks down is when it's called from a child process and the value in the array contains slashes. This leads to errors such as the following (line 156 is "output="${CONFIG_VALUES[${key}]}"):
config.sh: line 156: path/to/some/file: syntax error: operand expected (error token is "/to/some/file")
This is particularly obnoxious because it seems to be reading the value "path/to/some/file" just fine. It simply decides to announce a syntax error after doing so and falls over dead instead of echoing the value.
I've been trying to circumvent this by running the array lookup in a subshell, capturing the syntax failure, and grepping it for the value I need:
# A wrapper for accessing the CONFIG_VALUES array.
function get_config_value {
local key="${1^^}"
local output
if output="$(echo "${CONFIG_VALUES[${key}]}" 2>&1)"; then
echo "$output"
else
grep -oP "(?<=: ).*(?=: syntax error: operand expected)" <<< "$output"
fi
}
Unfortunately, it seems that BASH won't let me ignore the "syntax error" like that. I'm not sure where to go from here (well... Python, but I don't get to make that decision).
Any ideas?

Using Write command to create new syntax - problem with unwanted spaces

I am trying to run a command on a list of variables stored as values in a different file. To do that I am creating a new syntax based on the variable names, like this:
WRITE OUT="\Selection.sps"
/"VARIABLE ATTRIBUTE VARIABLES = Final_",Var1," ATTRIBUTE=selectVars('yes')." .
EXECUTE.
The Problem is between Final and Var1, I am getting 11 spaces. The file in which I want to use this macro has variable names as Final_Var1 (So in the new file, Final is added to each variable's Name). How can I remove the space so that the new variable can be referred to properly? Should I create a new file or COMPUTE and CONCAT commands?
The write command is limited like that - you can't avoid the spaces or use trim. For commands like the one you're working on there is no way to build the command within the write command - you have to build the text in advance and then put it in the write command, so -
strimg mycmd(a100).
compute mycmd=concat("VARIABLE ATTRIBUTE VARIABLES = Final_",
ltrim(string(Var1,f4)),
" ATTRIBUTE=selectVars('yes').").
WRITE OUT="\Selection.sps" /mycmd .
exe.
Note that this is not the only way to work on variable lists - you can use Python code within the syntax to build your variable lists more efficiently.
I have found a temporary solution, in order to remove the spaces from the variables, I am creating a new variable using:
*Add a variable to use in .sps file.
NUMERIC A(F4).
COMPUTE A = Var1.
ALTER TYPE A (A25).
STRING CMD (A100).
COMPUTE CMD = CONCAT("VARIABLE ATTRIBUTE VARIABLES = Final_", LTRIM (A) , ATTRIBUTE=selectVars('yes').").
EXECUTE.
WRITE OUT="File location\Selection.sps" /CMD.
EXECUTE.
and now a macro can be created using Selection.sps.
If a simpler way exists, please let me know!

Check whether a variable exists or not in EL Expression inside Oozie Hive action

I am trying to create a common template for Oozie workflow to be used for running different hive scripts. Each hive script has its own parameters.
On the Hive Action in Oozie, while setting parameters using PARAM tag, I need to check if a variable exists or not and if it does not exist, I need to default it to " ".
I tried,
<param>my_parameter_var=${empty my_parameter?" ":my_parameter}</param>
this works to only check if my_parameter is a null or empty string. This check fails if the variable doesn't exist at all; with the below error:
Error Code : EL_ERROR
Error Message : variable [my_parameter] cannot be resolved
Can someone please assist me on how to achieve this?
I am not sure if this is still needed but just in case, there is a way with combination of firstNotNull and wf:conf EL functions as below. Remove white spaces in param element from start and end.
< param>my_parameter_var=${firstNotNull(wf:conf('my_parameter'),' ')}< /param >
wf:conf shall return my_parameter's value if NOT empty/null/undefined or return empty string. Ref: https://oozie.apache.org/docs/3.2.0-incubating/WorkflowFunctionalSpec.html#a4.2.3_Workflow_EL_Functions
firstNotNull shall return first argument value if it is NOT empty/null or return second argument value. Ref: https://oozie.apache.org/docs/3.2.0-incubating/WorkflowFunctionalSpec.html#a4.2.1_Basic_EL_Constants
Thanks.

Concatenating strings fails when read from certain files

I have a web application that is deployed to a server. I am trying to create a script that amoing other things reads the current version of the web application from a properties file that is deployed along with the application.
The file looks like this:
//other content
version=[version number]
build=[buildnumber]
//other content
I want to create a variable that looks like this: version-buildnumber
Here is my script for it:
VERSION_FILE=myfile
VERSION_LINE="$(grep "version=" $VERSION_FILE)"
VERSION=${VERSION_LINE#$"version="}
BUILDNUMBER_LINE=$(grep "build=" $VERSION_FILE)
BUILDNUMBER=${BUILDNUMBER_LINE#$"build="}
THEVERSION=${VERSION}-${BUILDNUMBER}
The strange thing is that this works in some cases but not in others.
The problem I get is when I am trying to concatenate the strings (i.e. the last line above). In some cases it works perfectly, but in others characters from one string replace the characters from the other instead of being placed afterwards.
It does not work in these cases:
When I read from the deployed file
If I copy the deployed file to another location and read from there
It does work in these cases:
If I write a file from scratch and read from that one.
If I create my own file and then copy the content from the deployed file into my created file.
I find this very strange. Is there someone out there recognizing this?
It is likely that your files have carriage returns in them. You can fix that by running dos2unix on the file.
You may also be able to do it on the fly on the strings you're retrieving.
Here are a couple of ways:
Do it with sed instead of grep:
VERSION_LINE="$(sed -n "/version=/{s///;s/\r//g;p}" $VERSION_FILE)"
and you won't need the Bash parameter expansion to strip the "version=".
OR
Do the grep as you have it now and do a second parameter expansion to strip the carriage return.
VERSION=${VERSION_LINE#$"version="}
VERSION=${VERSION//$'\r'}
By the way, I recommend habitually using lowercase or mixed case variable names in order to reduce the chance of name collisions.
Given this foo.txt:
//other content
version=[version number]
build=[buildnumber]
//other content
you can extract a version-build string more easily with awk:
awk -F'=' '$1 == "version" { version = $2}; $1 == "build" { build = $2}; END { print version"-"build}' foo.txt
I don't know why your script doesn't work. Can you provide an example of erroneous output?
From this sentence:
In some cases it works perfectly, but in others characters from one string replace the characters from the other instead of being placed afterwards.
I can't understand what's actually going on (I'm not a native English speaker so it's probably my fault).
Cheers,
Giacomo

Managing a configuration file using sed via shell script

I need to manage a configuration file in Linux using a shell script, that will read and write settings to and from the cfg file. I have following function to write a new value of a key in existing config file used in my script.
set_setting() {
sed -i "s/$1=[^ ]*/$1=$2/" $3
}
Usage:
set_setting keyname NewValue /home/Config.cfg
Thus, this would replace the value of keyname in Config.cfg to NewValue.
I also have a function get_setting which uses source command to read the config file. It accepts similarly two parameters, keyname and the source config file, and returns the value of the supplied key.
Now the problem is that, I have config file as follows.
name=Abc
surname=Xyz
And when I call the set_setting function as set_setting name Def /home/Config.cfg, ideally it should change value of name from Abc to Def, but along with changing value of key name, it also changes the value of surname from Xyz to Def resulting into following in config file.
name=Def
surname=Def
I suspect this is due to having the term "name" common in both keys, as when I changed the key surname to surnames, it worked as expected and only value of name was changed. Also note that, the value for the key can be anything except the space.
I'm new to shell scripting and recently discovered sed command.
I've also refered to SO questions this and this. While both of them were quite helpful, I'm stuck with above mentioned situation.
You should anchor your match to the beginning of the line:
sed -i "s/^$1=[^ ]*/$1=$2/" $3
Note the ^ in front of $1. This regex operator anchors the expression to the beginning of the line, effectively requiring the name being everything from the first character to the = sign. There's also an end-of-line anchor called $ (which you do not need here).

Resources