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]

Reply via email to