Hi Miguel
First thanks for you detailed mail
I missed the "Centos Linux wotaskd", I'll dig deeper next time.
But it reminds me emails exchanged with Pascal (in French and off the list, sorry) which were following the thread with
subject "wotaskd womp and access denied" back in january 2009 ...
At that time the problem was the same: having admin wotaskd's requests not coming from 127.0.0.1 but from one of the
network card IP and being rejected.
I remember I have had a look in javawebobjects.jar and WOAdminAction.class where a call to
WOHostUtilities._isLocalInetAddress is made with the originating address (that why WOHostUtilities recall me something).
To test if an IP is local it use inetaddress.equals(WOApplication.application().hostAddress()); where hostAddress
instance is initialised with the "help" of InetAddress.getLocalHost()
I just made a quick search on google ( http://www.google.fr/search?q=+InetAddress.getLocalHost ) leading to
"InetAddress.getLocalHost()// ambiguous on Linux " http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037 pointing
the workaround about /etc/hosts.
In the replies of this bug someone point out NetworkInterface class and its methods getNetworkInterfaces() and
getInetAddresses(),it can be used to obtain all the server's IP address.
As Kieran suggest pushing in Wonder your WOHostUtilities version, I made some
changes to it:
_ property is er.extensions.localhostIps
_ it use methods of NetworkInterface instead of getLocalHost
warning: I don't even try to compile it
Also I add comments before each bloc of initLocalHosts which add address to the NSMutableArray. But I don't understand
the aim of the last one which does IP->hostname->IPs :
int i = localNSMutableArray.count();
for (int j = 0; j < i; ++j) {
InetAddress localInetAddress2 =
(InetAddress)localNSMutableArray.objectAtIndex(j);
try {
InetAddress[] arrayOfInetAddress3 =
InetAddress.getAllByName(localInetAddress2.getHostName());
_addInetAddressArray(arrayOfInetAddress3, localNSMutableArray);
} catch (Exception localException4) {
NSLog.err.appendln("<WOHostUtilities>: Couldn't get InetAddresses for '" +
localInetAddress2.getHostName() + "': " + localException4);
}
}
(I'm not sure that it will add new local IP)
Until this behaviour is fixed my rules for deployment are :
_ one WebObjects server:
* use 127.0.0.1
* /etc/hosts must have a line like "127.0.0.1 localhost.localdomain localhost"
_ multiple WebObjects servers:
* only use the IP corresponding to the hostname of the server (hostname musn't be localhost.localdomain and IP musn't
be 127.* ).
* hostname -f must return the fully qualified domain name. For that
- the system must set the hostname with "hostname servername.domain"
- /etc/hosts must have a line which must correspond to "a.b.c.d servername.domain servername" ( a.b.c.d is
the IP corresponding to the hostname)
Regards
Aurélien
On 11/20/2010 02:56 PM, Miguel Arroz wrote:
Hi!
(Sorry, Aurélien, I forgot to include the list in cc...)
no problem, sometimes I forgot too ;)
I don't remember all the details now, because some time has passed since I
wrote that class.
Anyway, the main idea behind was simple: for some reason, the JVM won't
report the full list of local addresses when requested to do so via the correct
API. This means that, if you have a multi-homed machine, you won't get all the
IP addresses assigned to the local interfaces as the result of that API.
The fix I sent to the list a few months ago allows you to define, in the
properties, the addresses you want to be considered local. This will add your
addresses to the ones already considered local by the JVM (like 127.0.0.1).
What's the point of all this? IIRC, we had servers with two network
interfaces - one in a private network (10.* addresses or so) and one with
public IPs facing the public Internet. Given this, we decided to make
everything run on internal IPs, except apache. This way, all the requests
between apache adaptor and apps, apache adaptor and wotaskd's, womonitor and
everything else, etc, would happen in the private, secured network. This had
the side effect of making the admin http requests that came from wotaskd to the
apps (requesting to terminate or turn on refusal of instances, for example)
having the source address as being 10.* instead of 127.0.0.1.
If you peek at the original code, you'll see those requests are ignored
unless they come from a local IP. So, I wrote that class to tell WO my 10.*
address was also a local IP.
I remember we tried to do some of the stuff you describe, like playing with
the hosts file, but it was of no use. As long as we binded the WO
infrastructure to our private network IPs, nothing would solve the issue but
that code change.
BTW this happened on FreeBSD. YMMV with other OS'es.
Regards,
Miguel Arroz
On 2010/11/19, at 23:21, Aurélien Minet wrote:
glad to see it is resolved
On 11/19/2010 10:50 PM, Kieran Kelleher wrote:
OK, first of all. Thanks to all who tried to help.
Miguel Arroz - you are a very smart man, and you should never give up your WO
career for goat-herding or farming in Portugal! :-)
So here is what worked for the finicky multi-IP linux box and its on/off
relationship with wotaskd:
I added Miguel's WOHostUtilities to ERExtensions, built and deployed the app.
I don't know Miguel's WOHostUtilities what is it made for ?
Note, WOHost needed to be set in wotaskd's Properties to the WoHost=192.168.3.168.
Setting it specifically to 127.0.0.1 resulted in WOMonitor red error message "Failed
to contact 192.168.3.168-1085".
Yes it's normal the WOPort of wotaskd isn't binded to 192.168.3.168 but
127.0.0.1 so no connection from the outside could be made. using 127.0.0.1 is
for setup with only one server.
Not setting it at all resulted in that Linux wotaskd not even receiving
requests from WOMonitor (confirmed with wotaskd debugging enabled) and not
responding at all to START instance requests.
If your hostname is localhost.localdomain as it correspond to 127.0.0.1 you
have to declare the host in JavaMonitor as 127.0.0.1 but with this setup you
can only have one server.
Only use localhost.localdomain for hostname if the server will be the only
WebObjects server (declared in the JavaMonitor as 127.0.0.1 or
localhost.localdomain)
In your case:
* no DNS server
* private LAN
* multiple WebObjects servers
you need :
* to set a hostname, ex: srvwo168.wo.local (or anything else but not
localhost.localdomain)
* add the line: "192.168.3.168 srvwo168.local srvwo168" in /etc/hosts on
srvwo168 (eventually on the server where JavaMonitor is running)
(even if DNS server can have hight availability, I don't rely on them only, I
always put in /etc/hosts all WO servers, Apache servers and databases servers)
* no need to use WOHost, all applications including wotaskd will bind their
WOPort to all IP
with this kind of setup :
_ applications will accept orders from the wotaskd as when they lookup where
the orders came from they found they were coming from the local server
_ wotaskd will start applications as it knows itself in the SiteConfig.xml
as 192.168.3.168 and finds that 192.168.3.168 is one of the server's IP .
note that it isn't specific to Linux, but applies to OS X, Solaris, FreeBSD ...
In WOMonitor I added a single argument with a list of all IP addresses of all
wotaskd hosts in the WOA subnet, like this:
-Dcom.survs.localhostIps=(192.168.3.140,192.168.3.160,192.168.3.163,192.168.3.165,192.168.3.161,192.168.3.161,192.168.3.168)
this is needed by Miguel's WOHostUtilities ? I understand that is the IP list
of your WebObjects servers but it's used to provide what functionality ?
( IP/hostname of WebObjects servers are in the SiteConfig.xml)
Now WOMonitor works for linux instances the same as for Mac OS X instances.
Yay! :-)
I am guessing (but not going messing with this server right now since it has
other services running on it that cannot be stopped for me to experiment) that
if the eth0 was on the WOA subnet, none of this might be neccessary.
No, you only need to make the server configuration right at the "dns"
(/etc/hosts) and hostname level, regardless the number of network cards or IP addresses
the server got.
In the case you don't want the hostname (ex: mysrv.local) to match a specific
IP, network card or subnet , you can declare it to 127.0.0.1 in /etc/hosts on
the server with a line like :
127.0.0.1 localhost.localdomain localhost mysrv.local mysrv
I hope all the mails in the thread will help future WebObjects servers setup
Regards
Aurélien
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-deploy mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-deploy/arroz%40guiamac.com
This email sent to [email protected]
package com.webobjects.appserver._private;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import org.apache.log4j.Logger;
import com.webobjects.appserver.WOApplication;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSLog;
import com.webobjects.foundation.NSMutableArray;
import er.extensions.foundation.ERXProperties;
/**
* <p>This class was re-written to support loading a new IP as a local IP to the local hosts list.
* This will authorize that IP to send management requests, like stopping the application, or
* turning on the refuse new instance setting. This is necessary if WO does not automatically
* add the needed IP to the local host list. It happens when you use private IPs.</p>
*
* <p>This version of the class will read a list of IPs from the er.extensions.localhostIps property.</p>
*
* @author arroz
*
*/
public class WOHostUtilities
{
static volatile NSArray _localHosts = null;
private static Logger logger = Logger.getLogger( WOHostUtilities.class );
@SuppressWarnings("unchecked")
static NSArray initLocalHosts()
{
NSMutableArray localNSMutableArray = new NSMutableArray();
// retrieve all IP address of all Network Interfaces of the host
Enumeration enumIface = null;
try {
enumIface = NetworkInterface.getNetworkInterfaces();
} catch (SocketException localException1) {
NSLog.err.appendln("<WOHostUtilities>: Couldn't invoke getNetworkInterfaces(): " + localException1);
}
while(enumIface.hasMoreElements()) {
NetworkInterface netIface = (NetworkInterface)e.nextElement();
for(Enumeration enumAddr = netIface.getInetAddresses(); e2.hasMoreElements();) {
_addInetAddress((InetAddress) enumAddr.nextElement() , localNSMutableArray);
}
}
// add IP address explicitly provided by ERX property: localhostIps
NSArray<String> ips = ERXProperties.arrayForKey( "er.extensions.localhostIps" );
if( ips != null ) {
for ( String ip : ips ) {
try {
InetAddress address = InetAddress.getByName( ip );
_addInetAddress( address, localNSMutableArray );
logger.debug( "Added the address " + address + " as a local host." );
} catch (Exception e) {
logger.error( "Could not add localhost IP " + ip );
}
}
}
// add all others hostname's IP of collected IP
int i = localNSMutableArray.count();
for (int j = 0; j < i; ++j) {
InetAddress localInetAddress2 = (InetAddress)localNSMutableArray.objectAtIndex(j);
try {
InetAddress[] arrayOfInetAddress3 = InetAddress.getAllByName(localInetAddress2.getHostName());
_addInetAddressArray(arrayOfInetAddress3, localNSMutableArray);
} catch (Exception localException2) {
NSLog.err.appendln("<WOHostUtilities>: Couldn't get InetAddresses for '" + localInetAddress2.getHostName() + "': " + localException2);
}
}
if (NSLog.debugLoggingAllowedForLevelAndGroups(3, 4L))
NSLog.out.appendln("<WOHostUtilities>: Initialized Local Host List: " + localNSMutableArray);
return localNSMutableArray;
}
static void _addInetAddressArray(InetAddress[] paramArrayOfInetAddress, NSMutableArray paramNSMutableArray)
{
if (paramArrayOfInetAddress != null)
for (int i = 0; i < paramArrayOfInetAddress.length; ++i)
_addInetAddress(paramArrayOfInetAddress[i], paramNSMutableArray);
}
static void _addInetAddress(InetAddress paramInetAddress, NSMutableArray paramNSMutableArray)
{
if ((paramInetAddress != null) && (!(paramNSMutableArray.containsObject(paramInetAddress))))
paramNSMutableArray.addObject(paramInetAddress);
}
public static NSArray getLocalHosts()
{
return _localHosts;
}
public static boolean isLocalInetAddress(InetAddress paramInetAddress, boolean paramBoolean)
{
if (paramInetAddress != null) {
if (WOApplication.application()._unsetHost)
return _isLocalInetAddress(paramInetAddress, paramBoolean);
return paramInetAddress.equals(WOApplication.application().hostAddress());
}
return false;
}
public static boolean isAnyLocalInetAddress(InetAddress paramInetAddress, boolean paramBoolean)
{
return ((_isLocalInetAddress(paramInetAddress, paramBoolean)) || (WOApplication.application().hostAddress().equals(paramInetAddress)));
}
public static boolean _isLocalInetAddress(InetAddress paramInetAddress, boolean paramBoolean)
{
boolean bool = false;
if (paramInetAddress != null) {
bool = _localHosts.containsObject(paramInetAddress);
if ((!(bool)) && (paramBoolean))
{
_localHosts = initLocalHosts();
bool = _localHosts.containsObject(paramInetAddress);
}
}
return bool;
}
static
{
_localHosts = initLocalHosts();
}
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-deploy mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-deploy/archive%40mail-archive.com
This email sent to [email protected]