Bug 900707 (JBPAPP6-1405)

Summary: Property substition breaks when the string "localhost" is used as part of the default value
Product: [JBoss] JBoss Enterprise Application Platform 6 Reporter: dereed
Component: ClusteringAssignee: Richard Achmatowicz <rachmato>
Status: CLOSED NOTABUG QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: 6.0.0CC: bbaranow, cdewolf, dereed, jkudrnac, myarboro, nmone, paul.ferraro, rachmato, sascha.moellering, smumford
Target Milestone: GA   
Target Release: EAP 6.1.0   
Hardware: Unspecified   
OS: Unspecified   
URL: http://jira.jboss.org/jira/browse/JBPAPP6-1405
Whiteboard:
Fixed In Version: Doc Type: Known Issue
Doc Text:
Property substitution does not work correctly when the string `localhost` was used as part of a default value in the JGroups subsystem configuration. Property substitution is a feature provided for JBoss Enterprise Application Platform 6 subsystems. However not all subsystems have it enabled, and some subsystems (like JGroups) do some of their own substitution. However this behavior is not standardized and differs from the supported subsystem properties. Red Hat recommends not to use property substitution with the JGroups subsystem until this issue is resolved.
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-09-11 18:07:24 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
standalone-ha.xml
none
0001-JBPAPP-9504-modify-flawed-implementation-of-getOrigi.patch
none
0001-JBPAPP-9504-use-the-PropertiesValueResolver-of-jboss.patch none

Description dereed 2012-07-12 19:43:18 UTC
Affects: Release Notes
project_key: JBPAPP6

Property substition breaks when the string "localhost" is used as part of the default value.

<stack name="tcp">
    ...
    <protocol type="TCPPING">
        <property name="initial_hosts">${some.property:localhost[7600]}</property>
    </protocol>

The value being used is the literal "${some.property:localhost[7600]}" instead of "localhost[7600]".
If "localhost" is replaced with "foo", it works correctly.

Comment 1 dereed 2012-07-16 15:30:41 UTC
Any valid DNS name or IP breaks the parsing.
(If "foo" is used, and it resolves to a DNS name then it parses incorrectly.  It if does not resolve to a DNS name, it parses correctly).


Comment 2 Chao Wang 2012-07-25 08:10:20 UTC
Dennis, Could you please give a more detail guideline for reproduction of this issue, or to verify the "initial_hosts" value. As I tried modify domain.xml by adding : 

<protocol type="TCPPING">
  <property name="initial_hosts">localhost[7600]</property>
  <property name="prot_range">0</property>
  <property name="timeout">3000</property>
  <property name="num_initial_members">3</property>
</protocol>

but, that won't breaks the parsing or server start-up.

Comment 3 dereed 2012-07-25 15:49:07 UTC
Read the description.  It's the property substitution that's broken.

Use a property substitution for initial_hosts with a default value containing any valid IP or DNS names
(and don't set the property, so it will try to use the default value).

<property name="initial_hosts">${some.property:localhost[7600]}</property>

Comment 4 Chao Wang 2012-07-31 07:02:36 UTC
In the JGroupsSubsystemXMLReader_1_1, I added some std-err output to see parsing property name and value from domain.xml. For the property substitution, no matter it can be resolve to a DNS name or not, it parses incorrectly such as:

If modify domain.xml by adding like:
<protocol type="TCPPING">
  property name="initial_hosts">${some.property:localhost[7600]}</property>
</protocol>

When start server, output info from my terminal are : 
[Host Controller] 14:50:08,485 INFO  [org.jboss.as.remoting] (MSC service thread 1-7) JBAS017100: Listening on 127.0.0.1:9999
[Host Controller] 14:50:08,874 ERROR [stderr] (Controller Boot Thread) property : initial_hosts
[Host Controller] 14:50:08,874 ERROR [stderr] (Controller Boot Thread) value : ${some.property:localhost[7600]}
[Host Controller] 14:50:08,874 ERROR [stderr] (Controller Boot Thread) properties : [("initial_hosts" => "${some.property:localhost[7600]}")]

On the other hand, if modify domain.xml by adding like:
<protocol type="TCPPING">
  <property name="initial_hosts">${some.property:foo[7600]}</property>
</protocol>

When start the server, output info from my terminal are :
[Host Controller] 14:51:19,668 INFO  [org.jboss.as.remoting] (MSC service thread 1-7) JBAS017100: Listening on 127.0.0.1:9999
[Host Controller] 14:51:20,046 ERROR [stderr] (Controller Boot Thread) property : initial_hosts
[Host Controller] 14:51:20,046 ERROR [stderr] (Controller Boot Thread) value : ${some.property:foo[7600]}
[Host Controller] 14:51:20,047 ERROR [stderr] (Controller Boot Thread) properties : [("initial_hosts" => "${some.property:foo[7600]}")]

Comment 5 dereed 2012-08-02 16:44:19 UTC
With ${some.property:foo[7600]}
-------------------------------
Caused by: java.lang.Exception: Property assignment of initial_hosts in TCPPING with original property value foo[7600] and converted to null could not be assigned
        at org.jgroups.stack.Configurator.resolveAndAssignField(Configurator.java:1154) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.createLayer(Configurator.java:444) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.createProtocols(Configurator.java:393) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.setupProtocolStack(Configurator.java:88) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.setupProtocolStack(Configurator.java:55) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.ProtocolStack.setup(ProtocolStack.java:465) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.JChannel.init(JChannel.java:795) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.JChannel.<init>(JChannel.java:166) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jboss.as.clustering.jgroups.MuxChannel.<init>(MuxChannel.java:37) [jboss-as-clustering-jgroups-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        at org.jboss.as.clustering.jgroups.JChannelFactory.createChannel(JChannelFactory.java:73) [jboss-as-clustering-jgroups-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        at org.jboss.as.clustering.jgroups.subsystem.ChannelService.start(ChannelService.java:40) [jboss-as-clustering-jgroups-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        at org.jboss.as.clustering.msc.AsynchronousService$1.run(AsynchronousService.java:65) [jboss-as-clustering-common-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        ... 4 more
Caused by: java.lang.Exception: Conversion of initial_hosts in TCPPING with original property value foo[7600] failed
        at org.jgroups.conf.PropertyHelper.getConvertedValue(PropertyHelper.java:85) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.resolveAndAssignField(Configurator.java:1148) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        ... 15 more
Caused by: java.net.UnknownHostException: foo
        at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) [rt.jar:1.6.0_24]
        at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:850) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAddressFromNameService(InetAddress.java:1201) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAllByName0(InetAddress.java:1154) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAllByName(InetAddress.java:1084) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAllByName(InetAddress.java:1020) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getByName(InetAddress.java:970) [rt.jar:1.6.0_24]
        at org.jgroups.stack.IpAddress.<init>(IpAddress.java:51) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]   
        at org.jgroups.util.Util.parseCommaDelimitedHosts(Util.java:2812) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.conf.PropertyConverters$InitialHosts.convert(PropertyConverters.java:63) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.conf.PropertyHelper.getConvertedValue(PropertyHelper.java:82) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        ... 16 more


With ${some.property:localhost[7600]}
-------------------------------------
Caused by: java.lang.Exception: String value could not be converted for method initial_hosts in TCPPING with default value ${some.property:localhost[7600]}.Exception is java.lang.Exception: Conversion of initial_hosts in TCPPING with original property value ${some.property:localhost[7600]} failed
        at org.jgroups.stack.Configurator.createInetAddressMap(Configurator.java:693) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.setupProtocolStack(Configurator.java:94) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.setupProtocolStack(Configurator.java:55) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.ProtocolStack.setup(ProtocolStack.java:465) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.JChannel.init(JChannel.java:795) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.JChannel.<init>(JChannel.java:166) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jboss.as.clustering.jgroups.MuxChannel.<init>(MuxChannel.java:37) [jboss-as-clustering-jgroups-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        at org.jboss.as.clustering.jgroups.JChannelFactory.createChannel(JChannelFactory.java:73) [jboss-as-clustering-jgroups-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        at org.jboss.as.clustering.jgroups.subsystem.ChannelService.start(ChannelService.java:40) [jboss-as-clustering-jgroups-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        at org.jboss.as.clustering.msc.AsynchronousService$1.run(AsynchronousService.java:65) [jboss-as-clustering-common-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
        ... 4 more
Caused by: java.lang.Exception: Conversion of initial_hosts in TCPPING with original property value ${some.property:localhost[7600]} failed
        at org.jgroups.conf.PropertyHelper.getConvertedValue(PropertyHelper.java:85) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.stack.Configurator.createInetAddressMap(Configurator.java:690) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        ... 13 more
Caused by: java.net.UnknownHostException: ${some.property:localhost
        at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) [rt.jar:1.6.0_24]
        at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:850) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAddressFromNameService(InetAddress.java:1201) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAllByName0(InetAddress.java:1154) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAllByName(InetAddress.java:1084) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getAllByName(InetAddress.java:1020) [rt.jar:1.6.0_24]
        at java.net.InetAddress.getByName(InetAddress.java:970) [rt.jar:1.6.0_24]
        at org.jgroups.stack.IpAddress.<init>(IpAddress.java:51) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]   
        at org.jgroups.util.Util.parseCommaDelimitedHosts(Util.java:2812) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.conf.PropertyConverters$InitialHosts.convert(PropertyConverters.java:63) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        at org.jgroups.conf.PropertyHelper.getConvertedValue(PropertyHelper.java:82) [jgroups-3.0.9.Final-redhat-1.jar:3.0.9.Final-redhat-1]
        ... 14 more


Comment 6 Chao Wang 2012-08-03 06:08:14 UTC
I actually don't receive these exceptions from my console when I start up server with domain mode and deploy a simple WebApp, what setting or commands you executed to trigger that?

Comment 7 baranowb 2012-08-03 07:20:44 UTC
Dennis what are exact steps to reproduce this?

Comment 8 dereed 2012-08-03 17:19:49 UTC
To reproduce:

Modify standalone/configuration/standalone-ha.xml:

Replace:
    <protocol type="MPING" socket-binding="jgroups-mping"/>

with:
                <protocol type="TCPPING">
                       <property name="initial_hosts">${some.property:localhost[7600]}</property>
                       <property name="port_range">0</property>
                       <property name="timeout">3000</property>
                       <property name="num_initial_members">3</property>
                </protocol>

Set the JGroups default-stack to "tcp".

bin/standalone.sh -c standalone-ha.xml

Error occurs during startup.

Comment 9 baranowb 2012-08-03 20:49:56 UTC
Great, thanks, seems like I made wangc poke around bad file.

Comment 10 Chao Wang 2012-08-06 01:04:21 UTC
thanks for that, Dennis

Comment 11 baranowb 2012-08-06 08:04:36 UTC
One little detail that escaped. To make AS7 start cluster, one needs to deploy distributable app: [https://github.com/jaysensharma/MiddlewareMagicDemos/blob/master/ClusterTest_WebApp/ClusterWebApp.war?raw=true]

Comment 12 baranowb 2012-08-06 08:07:38 UTC
Attachment: Added: standalone-ha.xml


Comment 13 dereed 2012-08-08 19:53:00 UTC
More info from the support case.
It also occurs when substitution occurs.

Instead of ${some.property:localhost[7600]}, using ${some.property} and -Dsome.property=localhost[7600].
With the error message changed to: Conversion of initial_hosts in TCPPING with original property value ${some.property} failed
(where as using an invalid DNS name such as -Dsome.property=foo[7600] the error messages show it is trying to use foo).


Comment 14 dereed 2012-08-08 21:17:19 UTC
I was able to dig into this a little deeper, and there are two issues:

1) the property substitution is not being done *at all* in EAP.
  This is part of a larger issue, where property substitution is missing for a whole lot of entries in standalone.xml/domain.xml.

2) since the property value is passed as is to JGroups, JGroups is running its own property substitution on it.
  There appears to be a bug related to this inside JGroups, where it tries to use the original value instead of the substituted value for specific properties containing IP addresses/host names.

I'll open a JGRP bug on #2.
Since JGroups does its own property substitution, which appears similar to what EAP would be doing, #1 probably isn't that important.


Comment 15 dereed 2012-08-08 22:23:50 UTC
#2 in my previous comment is actually a bug in AS7, not JGroups.

clustering/jgroups/src/main/java/org/jboss/as/clustering/jgroups/JChannelFactory#createProtocol
creates a subclass of org.jgroups.conf.ProtocolConfiguration that overrides getOriginalProperties().
The new implementation is flawed, because it returns the original values before property substitution, 
where the parent version returns the values *after* property substition (but before any other changes).

So this is a bug that needs fixed in AS7.

I don't see the purpose of the overridden getOriginalProperties, as the only difference I see from the original is this bug.


Comment 16 Chao Wang 2012-08-13 01:30:12 UTC
As Dennis mentioned, one solution is resolve property substitution in jgroups' code, simply remove the flawed implementation can make it works fine. 

Comment 17 Chao Wang 2012-08-13 01:30:12 UTC
Attachment: Added: 0001-JBPAPP-9504-modify-flawed-implementation-of-getOrigi.patch


Comment 18 Chao Wang 2012-08-13 05:45:51 UTC
Another way is using PropertieValueResolver class in jboss.common.beans, so we can make the property substitution in AS, not with JGroups. 

Comment 19 Chao Wang 2012-08-13 05:45:51 UTC
Attachment: Added: 0001-JBPAPP-9504-use-the-PropertiesValueResolver-of-jboss.patch


Comment 20 Richard Achmatowicz 2012-08-22 14:08:21 UTC
This JIRA issue has a subject which indicates a general EAP6 problem and yet the examples presented only involve JGroups property substitution. Why wasn't this simply marked as a clustering issue and directed to the people who should be handling it? 
 

Comment 21 Richard Achmatowicz 2012-08-22 23:50:40 UTC
Here's the current status:

1. property substitution was introduced for JGroups protocol properties in AS7-4828 and made it into 7.2.0.Alpha branch but not 7.1 branch - it represents a change in the management API and should not go directly into EAP 6.0.x, as Brian noted 

2. The issue that Dennis observed relates to the use of one of the constructors in org.jgroups.conf.ProtocolConfiguration. I fixed the issue described in JBPAPP-9504 by using the alternative constructor, which means that a limited version of property substitution in JGroups protocol properties can now be used in 7.1. It's limited in the sense that substitutions can be coded, but rather than the AS management API processing them and handing resolved values to JGroups, the substitution expressions are passed directly to JGroups which then evaluates them before creating the channel.

However, I think introducing this into 7.1 is not desirable for two reasons:
2.1 this is a new feature for 7.1 and really doesn't belong in a bug fix release
2.2 this new feature is similar to management layer property substitution but different enough that it will cause confusion ; in particular, the expressions entered are not represented as expressions in the management model, and it breaks some of our existing CLI management operations, such as /subsystem=jgroups/stack=tcp:export-native-configuration

I'd rather make a release note saying that it is not available in 6.0.1. but will be in 7.2.0.

Thoughts?

I'll probably submit the pull request for the fix in any case, but need to chat with Bela for a few minutes tomorrow before doing so.

Richard


Comment 22 Chao Wang 2012-08-23 04:09:58 UTC
Thanks, Richard,

the pull request of https://issues.jboss.org/browse/AS7-4828 is not merged to master yet, I tested from this commit code, it made the default value problem in this issue resolved.

Comment 24 Carlo de Wolf 2012-08-23 06:41:58 UTC
I do not see this as a feature issue.

The bug in itself must be fixed in a manner that will not cause an upwards compatibility problem with AS 7.2.

If that can't be done, then EAP 6.0.1 should throw an informative exception.

Comment 25 Richard Achmatowicz 2012-08-23 14:57:43 UTC
The issue was left unassigned because the correct default component "clustering" was not set, I expect.

I think an informative exception for branch 7.1 is the right way to go. System property substitution is not enabled by default for subsystem attribute values, and what we have here is a user who believes it is supported but in fact it is not (not yet, anyway). So an informative exception indicating this to the user that it's not enabled seems correct. 
 
 


Comment 26 Carlo de Wolf 2012-09-04 09:05:20 UTC
Link: Added: This issue is related to AS7-5182


Comment 27 Dana Mison 2012-10-16 01:05:55 UTC
Release Notes Docs Status: Added: Needs More Info
Writer: Added: Darrin


Comment 30 Dana Mison 2012-10-24 06:39:14 UTC
Dennis,

Thanks for the feedback, will be updating the release note shortly.

bq. "There are a number of subsystems that don't have it enabled that should. JGroups is one of them."

I don't suppose there is a list of those subsystems available ? Or a JIRA for them ?

Comment 37 dereed 2013-09-09 20:56:17 UTC
This should be working in 6.1 as https://issues.jboss.org/browse/AS7-4828 as per comment #21.

Comment 38 Richard Achmatowicz 2013-09-11 17:25:33 UTC
Agree with Dennis. I checked the EAP 6.x branch and the commit which fixes this issue is indeed present. So no further work need to be done here other than update the BZ status to reflect that.

Comment 39 Paul Ferraro 2013-09-11 18:07:24 UTC
Great. Let's close this as already fixed.