I've now tested FileInstall (and Utils) from trunk. Most things seem to
have been fixed now. In particular:
- I haven't seen any "false" write back of configuration changes.
- The variables are not evaluated more than once which makes things much
more deterministic
I've found one remaining issue though. The unescaping is still not
deterministic. Every time the value of a variable is needed, it is
unescaped. I've tested this in Karaf 2.3.3 by putting a file called
test.cfg in the etc directory. I then issue the following command from the
Karaf console to see how my configuration is evaluated:
config:list "(service.pid=test)"
What I have found is that the following contents of test.cfg:
a = $\\{var}
ab = ${a}b
abc = ${ab}c
evaluates to:
a = ${var}
ab = ${var}b
abc = ${var}bc
This is correct (according to me). Note that testing it this way I need two
backslash characters instead of one as you used Guillaume.
But, assume that I actually want my configuration to include a backslash,
like this:
a = $\\\\{var}
ab = ${a}b
abc = ${ab}c
This evaluates to:
a = $\{var}
ab = ${var}b
abc = ${var}bc
Here the variable "a" is OK. But when ${a} is used in the other variables,
the backslash is unescaped and lost. This can be seen even more clearly if
you add two more backslashes. Like this:
a = $\\\\\\\\{var}
ab = ${a}b
abc = ${ab}c
We then get:
a = $\\{var}
ab = $\{var}b
abc = ${var}bc
Thus, every time the variable "a" is evaluated, a backslash is removed.
It would be good if this could be fixed as well so that backslashes could
be part of the configuration in a deterministic way.
Note that the problematic configuration that I had no workaround for now
works fine. If I put this in the configuration file:
mydir=C:/temp
timestampedfile=$\\{file:onlyname\\}-$\\{date:now:yyyyMMddHHmmssSSS\\}.$\\{file:ext\\}
move=${mydir}/archive/$\\{date:now:yyyyMMdd\\}/${timestampedfile}
moveFailed=${mydir}/failed/${timestampedfile}
fromUri=file:${mydir}?move=${move}&moveFailed=${moveFailed}
It is evaluated to:
mydir = C:/temp
timestampedfile = ${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}
move =
C:/temp/archive/${date:now:yyyyMMdd}/${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}
moveFailed =
C:/temp/failed/${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}
fromUri =
file:C:/temp?move=C:/temp/archive/${date:now:yyyyMMdd}/${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}&moveFailed=C:/temp/failed/${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}
which is what I want. Note that I now only need two backslashes to make
this work.
But, if I wanted some part of my configuration to actually contain a
backslash then I would run into trouble.
/Bengt
2013/12/4 Bengt Rodehav <[email protected]>
> I'll give it a shot.
>
> Thanks,
>
> /Bengt
>
>
> 2013/12/4 Guillaume Nodet <[email protected]>
>
>> Not on the karaf side, but if you build felix utils, file install, and
>> change the karaf version to refer to those new ones and rebuild, it should
>> be ok.
>>
>>
>> 2013/12/4 Bengt Rodehav <[email protected]>
>>
>> > Will definitely test this out. Thanks a lot.
>> >
>> > I assume everything is checked in?
>> >
>> > /Bengt
>> > Den 4 dec 2013 16:09 skrev "Guillaume Nodet" <[email protected]>:
>> >
>> > > Both are parts of the game.
>> > > The order actually was significant as shown by the test case mainly
>> > because
>> > > of the order difference between the java util Properties object and
>> the
>> > > felix Properties object. The first one is relies on a Hashtable while
>> > the
>> > > second relies on a LinkedHashMap.
>> > > This is significant because of the way the substitution was done.
>> > > if you start from a = $\{var}, ab = ${a}b, abc = ${ab}c
>> > > you had the following steps:
>> > > a = $\{var}, ab = ${a}b, abc = ${ab}c
>> > > a = $\{var}, ab = ${var}b, abc = ${ab}c
>> > > a = $\{var}, ab = ${var}b, abc = bc
>> > > The reason is that substitution were done using already substituted
>> > > variables, so when computing ${ab}c, it was using
>> > > ${ab}c
>> > > ${var}bc
>> > > bc
>> > > instead of
>> > > ${ab}c
>> > > ${a}bc
>> > > $\{var}bc
>> > > ${var}bc
>> > > So the problem wan't really the order of the values, but the fact that
>> > the
>> > > substitution was done using already substituted values, which then
>> made
>> > the
>> > > order significant.
>> > >
>> > > Note that the result is now (and irrespective of the order of the
>> lines):
>> > > a = ${var}, ab = ${var}b, abc = ${var}bc
>> > >
>> > > So I think the escaping is now more deterministic. Please give it
>> some
>> > > testing and let me know if you still have problems in this area.
>> > >
>> > > 2013/12/4 Bengt Rodehav <[email protected]>
>> > >
>> > > > BTW. I did some experimenting with declaring the properties in
>> > different
>> > > > order in the configuration file. It did not seem to matter. I was
>> under
>> > > the
>> > > > impression that the recursive variable substitution is what makes it
>> > > > non-deterministic.
>> > > >
>> > > > If a property has been evaluated already it should not be evaluated
>> > again
>> > > > because another layer of the escape characters will then be removed.
>> > > >
>> > > > /Bengt
>> > > >
>> > > >
>> > > > 2013/12/4 Bengt Rodehav <[email protected]>
>> > > >
>> > > > > OK.
>> > > > >
>> > > > >
>> > > > > 2013/12/4 Guillaume Nodet <[email protected]>
>> > > > >
>> > > > >> Unfortunately, it does not seem to be sufficient, I'm
>> investigating
>> > > > >> further
>> > > > >>
>> > > > >>
>> > > > >> 2013/12/4 Bengt Rodehav <[email protected]>
>> > > > >>
>> > > > >> > I noticed that you seem to have fixed the issues I had reported
>> > > > >> Guillaume.
>> > > > >> > Thanks a lot! Looking forward to the next release.
>> > > > >> >
>> > > > >> > /Bengt
>> > > > >> >
>> > > > >> >
>> > > > >> > 2013/12/2 Bengt Rodehav <[email protected]>
>> > > > >> >
>> > > > >> > > Thanks Guillaume!
>> > > > >> > >
>> > > > >> > >
>> > > > >> > > 2013/12/2 Guillaume Nodet <[email protected]>
>> > > > >> > >
>> > > > >> > >> I'll try to have a look at those today or tomorrow.
>> > > > >> > >>
>> > > > >> > >>
>> > > > >> > >> 2013/12/2 Bengt Rodehav <[email protected]>
>> > > > >> > >>
>> > > > >> > >> > I've replaced FELIX-4332 with FELIX-4338 and FELIX-4339.
>> > > > >> > >> >
>> > > > >> > >> > I have attached a patch for FELIX-4338 and hope that
>> someone
>> > > can
>> > > > >> have
>> > > > >> > a
>> > > > >> > >> > look at it and possibly commit it.
>> > > > >> > >> >
>> > > > >> > >> > FELIX-4339 is trickier but I would appreciate a discussion
>> > > about
>> > > > >> how
>> > > > >> > >> this
>> > > > >> > >> > should be handled.
>> > > > >> > >> >
>> > > > >> > >> > /Bengt
>> > > > >> > >> >
>> > > > >> > >> >
>> > > > >> > >> > 2013/11/29 Bengt Rodehav <[email protected]>
>> > > > >> > >> >
>> > > > >> > >> > > I've tested more with the proposed change in order to
>> stop
>> > > > >> > >> FileInstall to
>> > > > >> > >> > > incorrectly change the contents of the configuration
>> file
>> > > > >> (problem
>> > > > >> > b)
>> > > > >> > >> > from
>> > > > >> > >> > > my previous post). It seems to work fine. I would really
>> > like
>> > > > >> that
>> > > > >> > to
>> > > > >> > >> be
>> > > > >> > >> > > fixed. Would you like me to create a patch atttached to
>> the
>> > > > JIRA?
>> > > > >> > >> > >
>> > > > >> > >> > > Problem a) is probably not trivial to fix. I've
>> > experimented
>> > > a
>> > > > >> lot
>> > > > >> > and
>> > > > >> > >> > > it's very hard for me to foresee how many escape
>> > characters I
>> > > > >> need
>> > > > >> > in
>> > > > >> > >> > > different circumstances. One real life example for me is
>> > how
>> > > I
>> > > > >> > >> configure
>> > > > >> > >> > an
>> > > > >> > >> > > integration service that uses a Camel route underneath.
>> If
>> > I
>> > > > put
>> > > > >> the
>> > > > >> > >> > > followiing contents in a test.cfg file:
>> > > > >> > >> > >
>> > > > >> > >> > > *mydir=C:/temp*
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> >
>> > > > >> > >>
>> > > > >> >
>> > > > >>
>> > > >
>> > >
>> >
>> *timestampedfile=$\\\\{file:onlyname\\\\}-$\\\\{date:now:yyyyMMddHHmmssSSS\\\\}.$\\\\{file:ext\\\\}*
>> > > > >> > >> > >
>> > > > >>
>> *move=${mydir}/archive/$\\{date:now:yyyyMMdd\\}/${timestampedfile}*
>> > > > >> > >> > > *moveFailed=${mydir}/failed/${timestampedfile}*
>> > > > >> > >> > >
>> > *fromUri=file:${mydir}?move=${move}&moveFailed=${moveFailed}*
>> > > > >> > >> > >
>> > > > >> > >> > > And execute the following command:
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > > *config:list "(service.pid=test)"*
>> > > > >> > >> > >
>> > > > >> > >> > > I get the following output:
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >>
>> *----------------------------------------------------------------*
>> > > > >> > >> > > *Pid: test*
>> > > > >> > >> > > *BundleLocation: null*
>> > > > >> > >> > > *Properties:*
>> > > > >> > >> > > * moveFailed =
>> > > > >> > >> > >
>> > > > >> > >> >
>> > > > >> > >>
>> > > > >> >
>> > > > >>
>> > > >
>> > >
>> >
>> C:/temp/failed/${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}*
>> > > > >> > >> > > * mydir = C:/temp*
>> > > > >> > >> > > * timestampedfile =
>> > > > >> > >> > >
>> > > > $\{file:onlyname\}-$\{date:now:yyyyMMddHHmmssSSS\}.$\{file:ext\}*
>> > > > >> > >> > > * service.pid = test*
>> > > > >> > >> > > * fromUri =
>> > > > >> > >> > >
>> > > > >>
>> file:C:/temp?move=C:/temp/archive//-.&moveFailed=C:/temp/failed/-.*
>> > > > >> > >> > > * move =
>> > > > >> > >> > >
>> > > > >> > >> >
>> > > > >> > >>
>> > > > >> >
>> > > > >>
>> > > >
>> > >
>> >
>> C:/temp/archive/${date:now:yyyyMMdd}/${file:onlyname}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}*
>> > > > >> > >> > > * felix.fileinstall.filename =
>> > > > >> > >> > > file:/C:/dev/karaf/connect/common/etc/test.cfg*
>> > > > >> > >> > >
>> > > > >> > >> > > Thus, the variables "move" and "moveFailed" looks the
>> way I
>> > > > want
>> > > > >> but
>> > > > >> > >> the
>> > > > >> > >> > > final variable "fromUri" is messed up because of an
>> extra
>> > > > >> variable
>> > > > >> > >> > > substitution.
>> > > > >> > >> > >
>> > > > >> > >> > > I haven't managed to come up with any number of
>> backslashes
>> > > > that
>> > > > >> > will
>> > > > >> > >> > > produce the correct result for me.
>> > > > >> > >> > >
>> > > > >> > >> > > The only workaround I have right now is to not use
>> > variables
>> > > at
>> > > > >> all.
>> > > > >> > >> It
>> > > > >> > >> > > does, however, make the configuration files extremely
>> > verbose
>> > > > and
>> > > > >> > it's
>> > > > >> > >> > easy
>> > > > >> > >> > > to introduce errors that way.
>> > > > >> > >> > >
>> > > > >> > >> > > Presently, variable substitution is very unpredictable
>> > since
>> > > > it's
>> > > > >> > >> being
>> > > > >> > >> > > done in a recursive way. I would prefer doing it in an
>> > > > iterative
>> > > > >> > >> manner
>> > > > >> > >> > to
>> > > > >> > >> > > make it predictable. E g "${a}" should always evaluate
>> to
>> > the
>> > > > >> same
>> > > > >> > >> value
>> > > > >> > >> > no
>> > > > >> > >> > > matter where in the configuration file it is referenced.
>> > > > >> > >> > >
>> > > > >> > >> > > /Bengt
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > > 2013/11/28 Bengt Rodehav <[email protected]>
>> > > > >> > >> > >
>> > > > >> > >> > >> I've investigated this a bit more. There are actually
>> two
>> > > > >> different
>> > > > >> > >> > >> problems:
>> > > > >> > >> > >>
>> > > > >> > >> > >> a) The number of escape characters I need depends on
>> from
>> > > > where
>> > > > >> I
>> > > > >> > >> > >> reference the variable. For every indirection I need to
>> > > double
>> > > > >> the
>> > > > >> > >> > number
>> > > > >> > >> > >> of backslashes. This also means that all uses of a
>> > variable
>> > > > >> > >> containing
>> > > > >> > >> > >> escape characters must be used from the same level of
>> > > > >> indirection.
>> > > > >> > A
>> > > > >> > >> bit
>> > > > >> > >> > >> complicated but it's due to the fact that all variables
>> > are
>> > > > >> > evaluated
>> > > > >> > >> > >> dynamically. This means that unescaping can occur
>> several
>> > > > times.
>> > > > >> > >> > >>
>> > > > >> > >> > >> b) FileInstall incorrectly thinks that a configuration
>> > > > property
>> > > > >> is
>> > > > >> > >> > >> changed and therefore overwrites the property with the
>> > > > evaluated
>> > > > >> > >> value.
>> > > > >> > >> > >>
>> > > > >> > >> > >> I think I've found the reason (and possibly a
>> solution) to
>> > > b).
>> > > > >> > >> > >>
>> > > > >> > >> > >> In the ConfigInstaller.setConfig() method the
>> properties
>> > are
>> > > > >> read
>> > > > >> > >> from a
>> > > > >> > >> > >> configuration file and propagated as a configuration.
>> Here
>> > > is
>> > > > an
>> > > > >> > >> excerpt
>> > > > >> > >> > >> from that method:
>> > > > >> > >> > >>
>> > > > >> > >> > >> * final Properties p = new
>> Properties();*
>> > > > >> > >> > >> * in.mark(1);*
>> > > > >> > >> > >> * boolean isXml = in.read() == '<';*
>> > > > >> > >> > >> * in.reset();*
>> > > > >> > >> > >> * if (isXml) {*
>> > > > >> > >> > >> * p.loadFromXML(in);*
>> > > > >> > >> > >> * } else {*
>> > > > >> > >> > >> * p.load(in);*
>> > > > >> > >> > >> * }*
>> > > > >> > >> > >> *
>> > > InterpolationHelper.performSubstitution((Map)
>> > > > >> p,
>> > > > >> > >> > >> context);*
>> > > > >> > >> > >> * ht.putAll(p);*
>> > > > >> > >> > >>
>> > > > >> > >> > >> Note that the file is read using Java's standard
>> > Properties
>> > > > >> class.
>> > > > >> > >> The
>> > > > >> > >> > >> unescaping is also done by that class. Then, at the
>> end,
>> > the
>> > > > >> > variable
>> > > > >> > >> > >> substitution is done as a separate call.
>> > > > >> > >> > >>
>> > > > >> > >> > >> Then look at the ConfigInstaller.configurationEvent()
>> > > method:
>> > > > >> > >> > >>
>> > > > >> > >> > >> * if (configurationEvent.getType() ==
>> > > > >> > >> > >> ConfigurationEvent.CM_UPDATED)*
>> > > > >> > >> > >> * {*
>> > > > >> > >> > >> * try*
>> > > > >> > >> > >> * {*
>> > > > >> > >> > >> * Configuration config =
>> > > > >> > >> > >> getConfigurationAdmin().getConfiguration(*
>> > > > >> > >> > >> *
>> > > > >> > >> > configurationEvent.getPid(),*
>> > > > >> > >> > >> *
>> > > > >> > >> > >> configurationEvent.getFactoryPid());*
>> > > > >> > >> > >> * Dictionary dict =
>> > config.getProperties();*
>> > > > >> > >> > >> * String fileName = (String) dict.get(
>> > > > >> > >> > >> DirectoryWatcher.FILENAME );*
>> > > > >> > >> > >> * File file = fileName != null ?
>> > > > >> > >> fromConfigKey(fileName)
>> > > > >> > >> > :
>> > > > >> > >> > >> null;*
>> > > > >> > >> > >> * if( file != null && file.isFile() )
>> {*
>> > > > >> > >> > >> * if( fileName.endsWith( ".cfg" ) )*
>> > > > >> > >> > >> * {*
>> > > > >> > >> > >> *
>> > > > >> > org.apache.felix.utils.properties.Properties
>> > > > >> > >> > >> props = new
>> org.apache.felix.utils.properties.Properties(
>> > > > file,
>> > > > >> > >> context
>> > > > >> > >> > );*
>> > > > >> > >> > >>
>> > > > >> > >> > >> Note that now the configuration file is read using
>> > > > >> > >> > >> org.apache.felix.utils.properties.Properties class. It
>> > turns
>> > > > out
>> > > > >> > that
>> > > > >> > >> > they
>> > > > >> > >> > >> don't produce identical results. I haven't investigated
>> > > > exactly
>> > > > >> how
>> > > > >> > >> they
>> > > > >> > >> > >> differ but they do.
>> > > > >> > >> > >>
>> > > > >> > >> > >> A simple test:
>> > > > >> > >> > >>
>> > > > >> > >> > >> 1. Create a configuration file with the following
>> content:
>> > > > >> > >> > >>
>> > > > >> > >> > >> a=$\\\\{var}
>> > > > >> > >> > >> ab=${a}b
>> > > > >> > >> > >> abc=${ab}c
>> > > > >> > >> > >>
>> > > > >> > >> > >> 2. Add the following line at the end:
>> > > > >> > >> > >>
>> > > > >> > >> > >> d=foo
>> > > > >> > >> > >>
>> > > > >> > >> > >> 3. FileInstall will now incorrectly change the
>> contents of
>> > > the
>> > > > >> > >> > >> configuration file to:
>> > > > >> > >> > >>
>> > > > >> > >> > >> a=$\\\\{var}
>> > > > >> > >> > >> ab=${a}b
>> > > > >> > >> > >> abc = ${var}bc
>> > > > >> > >> > >> d=foo
>> > > > >> > >> > >>
>> > > > >> > >> > >> Now if I change the ConfigInstaller.setConfig() method
>> to
>> > > the
>> > > > >> > >> following:
>> > > > >> > >> > >>
>> > > > >> > >> > >> *org.apache.felix.utils.properties.Properties p = new
>> > > > >> > >> > >> org.apache.felix.utils.properties.Properties( f,
>> context
>> > );*
>> > > > >> > >> > >> *InterpolationHelper.performSubstitution((Map) p,
>> > context);*
>> > > > >> > >> > >>
>> > > > >> > >> > >> Then FileInstall will not incorrectly change the
>> contents
>> > of
>> > > > the
>> > > > >> > >> > >> configuration file.
>> > > > >> > >> > >>
>> > > > >> > >> > >> I propose to do this change in order to solve problem
>> b)
>> > > > above.
>> > > > >> I
>> > > > >> > >> > >> appreciate if you have any thoughts on this.
>> > > > >> > >> > >>
>> > > > >> > >> > >> I realize that problem a) is trickier due to the
>> dynamic
>> > > > nature
>> > > > >> of
>> > > > >> > >> > >> variable substitution. I haven't yet determined how I
>> > think
>> > > > the
>> > > > >> > >> escape
>> > > > >> > >> > >> characters should be handled but the current situation
>> is
>> > > not
>> > > > >> > ideal.
>> > > > >> > >> > >>
>> > > > >> > >> > >> /Bengt
>> > > > >> > >> > >>
>> > > > >> > >> > >>
>> > > > >> > >> > >>
>> > > > >> > >> > >>
>> > > > >> > >> > >> 2013/11/28 Bengt Rodehav <[email protected]>
>> > > > >> > >> > >>
>> > > > >> > >> > >>> JIRA created:
>> > > > >> > >> > >>>
>> > > > >> > >> > >>> https://issues.apache.org/jira/browse/FELIX-4332
>> > > > >> > >> > >>>
>> > > > >> > >> > >>> /Bengt
>> > > > >> > >> > >>>
>> > > > >> > >> > >>>
>> > > > >> > >> > >>> 2013/11/28 Bengt Rodehav <[email protected]>
>> > > > >> > >> > >>>
>> > > > >> > >> > >>>> I've come up with easily reproducable errors using
>> Karaf
>> > > > >> 2.3.3:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> - Install a fresh Karaf 2.3.3
>> > > > >> > >> > >>>> - Add the following line to etc/custom.properties:
>> > > > >> > >> > >>>> felix.fileinstall.enableConfigSave = true
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> Create a file etc/test.cfg with the following
>> contents:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> a=$\\{var}
>> > > > >> > >> > >>>> ab=${a}b
>> > > > >> > >> > >>>> abc=${ab}c
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> I expect this to be evaluated to:
>> > > > >> > >> > >>>> a=$\{var}
>> > > > >> > >> > >>>> ab=$\{var}b
>> > > > >> > >> > >>>> abc=$\{var}bc
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> But if I execute the Karaf command:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> config:list "(service.pid=test)"
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> I get:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>>
>> > > > >> ----------------------------------------------------------------
>> > > > >> > >> > >>>> Pid: test
>> > > > >> > >> > >>>> BundleLocation: null
>> > > > >> > >> > >>>> Properties:
>> > > > >> > >> > >>>> service.pid = test
>> > > > >> > >> > >>>> a = ${var}
>> > > > >> > >> > >>>> abc = bc
>> > > > >> > >> > >>>> felix.fileinstall.filename =
>> > > > >> > >> > >>>> file:/C:/dev/Karaf/apache-karaf-2.3.3/etc/test.cfg
>> > > > >> > >> > >>>> ab = b
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> My interpretation of this is that the variable "a"
>> has
>> > > been
>> > > > >> > >> correctly
>> > > > >> > >> > >>>> evaluated. But, when evalutating the variable "ab" it
>> > > seems
>> > > > >> that
>> > > > >> > >> the
>> > > > >> > >> > >>>> variable "a" is evaluated again despite the fact
>> that it
>> > > has
>> > > > >> > >> already
>> > > > >> > >> > been
>> > > > >> > >> > >>>> evaluated. FileInstall now looks for the value of a
>> > > variable
>> > > > >> > called
>> > > > >> > >> > "var"
>> > > > >> > >> > >>>> which evalutes to an empty string because there is no
>> > such
>> > > > >> > >> variable.
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> The variable "abc" consequently evaluates to "bc"
>> since
>> > > the
>> > > > >> > >> variable
>> > > > >> > >> > >>>> "ab" has been evaluated to "b".
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> To make it even worse, now change the first row in
>> > > test.cfg
>> > > > >> to:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> a=$\\\\{var}
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> We now get:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>>
>> > > > >> ----------------------------------------------------------------
>> > > > >> > >> > >>>> Pid: test
>> > > > >> > >> > >>>> BundleLocation: null
>> > > > >> > >> > >>>> Properties:
>> > > > >> > >> > >>>> service.pid = test
>> > > > >> > >> > >>>> a = $\{var}
>> > > > >> > >> > >>>> abc = ${var}bc
>> > > > >> > >> > >>>> felix.fileinstall.filename =
>> > > > >> > >> > >>>> file:/C:/dev/Karaf/apache-karaf-2.3.3/etc/test.cfg
>> > > > >> > >> > >>>> ab = ${var}b
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> Thus we get the same phenomenom. The variable "a" is
>> > > > evaluated
>> > > > >> > >> > >>>> differently if it is evaluated on its own or as part
>> of
>> > > > >> another
>> > > > >> > >> > expression.
>> > > > >> > >> > >>>> But, due to having configured FileInstall to write
>> back
>> > > > >> changes,
>> > > > >> > >> the
>> > > > >> > >> > >>>> contents of the test.cfg is now changed by
>> FileInstall
>> > > > despite
>> > > > >> > the
>> > > > >> > >> > fact
>> > > > >> > >> > >>>> that the configuration has not changed at all. The
>> > > contents
>> > > > of
>> > > > >> > >> > test.cfg is
>> > > > >> > >> > >>>> now:
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> a=$\\\\{var}
>> > > > >> > >> > >>>> ab=${a}b
>> > > > >> > >> > >>>> abc = ${var}bc
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> The "abc" variable has been altered. FileInstall has
>> > > > >> incorrectly
>> > > > >> > >> > >>>> determined that its value has changed.
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> This is clearly a bug. I will create a JIRA.
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> /Bengt
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>> 2013/11/26 Bengt Rodehav <[email protected]>
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>>> I'm using Apache Karaf 2.3.3 which comes with
>> > FileInstall
>> > > > >> > 3.2.6. I
>> > > > >> > >> > >>>>> have set the felix.fileinstall.enableConfigSave
>> > property
>> > > to
>> > > > >> true
>> > > > >> > >> in
>> > > > >> > >> > order
>> > > > >> > >> > >>>>> to have FileInstall write back configuration
>> changes to
>> > > the
>> > > > >> > file.
>> > > > >> > >> > Normally
>> > > > >> > >> > >>>>> all configuration changes are done by editing the
>> > > > >> configuration
>> > > > >> > >> file
>> > > > >> > >> > but
>> > > > >> > >> > >>>>> there is one property that I change programmatically
>> > > using
>> > > > >> > >> > ConfigAdmin (an
>> > > > >> > >> > >>>>> "enable" property to start/stop my service). I am
>> > > dependent
>> > > > >> on
>> > > > >> > >> that
>> > > > >> > >> > >>>>> property being persisted in the configuration file
>> > which
>> > > is
>> > > > >> why
>> > > > >> > I
>> > > > >> > >> > set the
>> > > > >> > >> > >>>>> enableConfigSave property to true.
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> When configuring FileInstall to write back
>> > configuration
>> > > > >> changes
>> > > > >> > >> to
>> > > > >> > >> > >>>>> the configuration file, it is important that
>> variables
>> > > are
>> > > > >> not
>> > > > >> > >> > substituted
>> > > > >> > >> > >>>>> for the evaluated value. This normally works since
>> > > > >> FileInstall
>> > > > >> > >> > evalutates
>> > > > >> > >> > >>>>> the property in the configuration file and compares
>> it
>> > > with
>> > > > >> the
>> > > > >> > >> > >>>>> configuration admin's value. If they are the same,
>> the
>> > > > value
>> > > > >> in
>> > > > >> > >> the
>> > > > >> > >> > >>>>> configuration file is kept unchanged.
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> However, when using the escape character this is
>> > broken.
>> > > In
>> > > > >> my
>> > > > >> > >> case
>> > > > >> > >> > >>>>> I'm using Apache Camel underneath. When configuring
>> > > routes
>> > > > >> via
>> > > > >> > the
>> > > > >> > >> > config
>> > > > >> > >> > >>>>> admin, I sometimes need to set a value to
>> > > > >> > >> > >>>>> "${expression-to-be-evaluated-by-camel}". I
>> therefore
>> > > > escape
>> > > > >> the
>> > > > >> > >> "{"
>> > > > >> > >> > and
>> > > > >> > >> > >>>>> "}" to stop FileInstall from trying to evaluate the
>> > > > >> expression.
>> > > > >> > >> Like
>> > > > >> > >> > this:
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> $\\{expression-to-be-evaluated-by-camel\\}
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> This also normally works but not when I have an
>> > > > indirection.
>> > > > >> E g
>> > > > >> > >> when
>> > > > >> > >> > >>>>> specifying the following:
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> a=$\\{var}
>> > > > >> > >> > >>>>> ab=${a}b
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> FileInstall will change the configuration file to:
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> a=$\\{var}
>> > > > >> > >> > >>>>> ab = ${var}b
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> Note that the variable "ab" has now been expanded
>> and
>> > > > written
>> > > > >> > >> back to
>> > > > >> > >> > >>>>> the configuration file even if neither of the
>> variables
>> > > "a"
>> > > > >> and
>> > > > >> > >> "ab"
>> > > > >> > >> > have
>> > > > >> > >> > >>>>> been changed.
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> I think this is because FileInstall does the
>> following:
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> 1. Calculates the value of "a" to "$\{var}
>> > > > >> > >> > >>>>> 2. Calculates the value of "b" to "${var}b
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> Note that every evaluation will perform
>> "unescaping".
>> > > This
>> > > > >> means
>> > > > >> > >> that
>> > > > >> > >> > >>>>> an extra "unescaping" will be done for every
>> > indirection
>> > > > >> which
>> > > > >> > >> fools
>> > > > >> > >> > >>>>> FileInstall into thinking that the property has been
>> > > > changed.
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> I'm not exactly sure how this should be fixed in
>> > > > FileInstall.
>> > > > >> > One
>> > > > >> > >> > idea
>> > > > >> > >> > >>>>> is to never "unescape" already evaluated variables.
>> > > > Actually
>> > > > >> I
>> > > > >> > >> think
>> > > > >> > >> > this
>> > > > >> > >> > >>>>> is probably what would fix this...
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> Does anybody have any ideas about this? Should I
>> > create a
>> > > > >> JIRA?
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>> /Bengt
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>>
>> > > > >> > >> > >>>>
>> > > > >> > >> > >>>
>> > > > >> > >> > >>
>> > > > >> > >> > >
>> > > > >> > >> >
>> > > > >> > >>
>> > > > >> > >>
>> > > > >> > >>
>> > > > >> > >> --
>> > > > >> > >> -----------------------
>> > > > >> > >> Guillaume Nodet
>> > > > >> > >> ------------------------
>> > > > >> > >> Red Hat, Open Source Integration
>> > > > >> > >>
>> > > > >> > >> Email: [email protected]
>> > > > >> > >> Web: http://fusesource.com
>> > > > >> > >> Blog: http://gnodet.blogspot.com/
>> > > > >> > >>
>> > > > >> > >
>> > > > >> > >
>> > > > >> >
>> > > > >>
>> > > > >
>> > > > >
>> > > >
>> > >
>> >
>>
>
>