Re: Select the output-network-interface to call an axis-webservice

2006-05-17 Thread Carsten Schmidt
Hi Alain,
Hi Rodrigo,

that's great! Your solution-samples are looking incredible. I hope, I'll
find time to realise it the next days.

I'm just a bit confused about the client-config.wsdd-file because I
don't have such a file right now.
Sure I know the server-config.wsdd, but a clientprogram will not be
deployed, or will it?

And if the program never used this wsdd before, how can I tell it to do
so?
My experiences with axis are quite simple yet, so I am not sure I
haven't overlooked something important about this.

BTW: At the moment I'm using libraries from axis 1.3 (Download archive
from october 05).

Anyway, let me tell you I really appreciate to your support so far.

Carsten


Am Dienstag, den 16.05.2006, 16:47 +0200 schrieb Rodrigo Ruiz:
 CommonsHTTPSender is easier to subclass and modify. I pass you a
 simple  
 subclass that could do the trick :-)
 
 HTH, 
 Rodrigo
 
 
 
 package org.rodrisoft;
 
 import java.io.FileInputStream; 
 import java.io.InputStream; 
 import java.net.InetAddress; 
 import java.net.URL; 
 import java.util.HashMap; 
 import java.util.Hashtable; 
 import java.util.Iterator; 
 import java.util.Map; 
 import java.util.Properties;
 
 import org.apache.axis.MessageContext; 
 import org.apache.axis.transport.http.CommonsHTTPSender; 
 import org.apache.commons.httpclient.HostConfiguration; 
 import org.apache.commons.httpclient.HttpClient;
 
 /** 
   * Sender implementation that uses Jakarta Commons HTTP for  
 transmission, and 
   * implements a routing map table to select a local address
 depending  
 on the 
   * remote address to connect to. 
   * p 
   * This sender can be configured in the client-config.wsdd file like
 this: 
   * pre 
   * lt;transport name=http 
   *   pivot=java:org.rodrisoft.RoutedCommonsHTTPSender 
   *   lt;parameter name=map-file
 value=path/to/map/file.properties/ 
   *   lt;parameter name=map:remote-addr value=10.33.5.67/ 
   * lt;/transport 
   * /pre 
   * p 
   * The first parameter specifies a .properties file containing pairs
 in 
   * the form: 
   * 
   * pre 
   *   remote-addr=remote-addr 
   * /pre 
   * 
   * The second parameter is an example of how to specify a single
 route 
   * table entry directly in the .wsdd file. 
   * p 
   * The first parameter allows to share the route table among several 
   * protocols. 
   * p 
   * The local binding address can also be specified through the
 message 
   * context. This allows services and handlers set the local address,
 and 
   * provide smarter routing algorithms. 
   * p 
   * Original work from Davanum Srinivas. 
   * 
   * @author Davanum Srinivas ([EMAIL PROTECTED]) 
   * @author Rodrigo Ruiz ([EMAIL PROTECTED]) 
   * @version 1.0 
   */ 
 public class RoutedCommonsHTTPSender extends CommonsHTTPSender {
 
/** 
 * codeserialVersionUID/code attribute. 
 */ 
private static final long serialVersionUID = -8610352356067978620L;
 
/** 
 * MessageContext Property name for setting the local bind
 address. 
 */ 
public static final String LOCAL_BIND_ADDRESS =
 local.bind.address;
 
/** 
 * Local Bind Address Route Map. 
 */ 
private final Map routeTable = new HashMap();
 
/** 
 * Flag that controls bindMap synchronization. 
 */ 
private boolean dirty = true;
 
public synchronized void setOption(String name, Object value) { 
  this.dirty = true; 
  super.setOption(name, value); 
}
 
public synchronized boolean setOptionDefault(String name, 
 Object value) { 
  this.dirty = true; 
  return super.setOptionDefault(name, value); 
}
 
public synchronized void setOptions(Hashtable options) { 
  this.dirty = true; 
  super.setOptions(options); 
}
 
protected HostConfiguration getHostConfiguration(HttpClient
 client, 
MessageContext context, URL targetURL) {
 
  HostConfiguration config = super.getHostConfiguration(client, 
context, 
targetURL);
 
  if (targetURL != null) { 
String remoteHost = targetURL.getHost(); 
InetAddress localAddr = getRouteFor(context, remoteHost); 
if (localAddr != null) { 
  config.setLocalAddress(localAddr); 
} 
  }
 
  return config; 
}
 
/** 
 * This utility method allows to force the route table to be
 rebuilt. 
 * It can be useful if the route table file is modified, and we
 can 
 * manage to get the instance of this handler. 
 */ 
public void rebuildTable() { 
  this.dirty = true; 
}
 
/** 
 * Gets a route for the specified remote address, allowing it to
 be 
 * specified through a Message Context parameter. 
 * 
 * @param ctx   The message context 
 * @param host  The remote host to map 
 * @return  The mapped address, or null if none found 
 

Re: Select the output-network-interface to call an axis-webservice

2006-05-16 Thread Carsten Schmidt
Hi Rodrigo,
these ideas are very interesting.

First of all, thanks a lot for that.

But for the first way of making the host address configurable, I still
have to ask you, how to do that in detail?

I don't mean how to read the address from a properties file, but how can
I set the value?

Carsten


Am Montag, den 15.05.2006, 17:28 +0200 schrieb Rodrigo Ruiz:
 Carsten,
 
 In fact, there are several ways to handle your situation, but I
 guess  
 almost none of them is as simple as adding some lines to your client  
 code. The ones I know are:
 
 - Make the host address configurable. That is, read the host address  
 from a configuration file. I know this is not what you are asking
 for,  
 but it is probably the only easy workaround to your problem. In fact,
 I  
 think it will be the only one that will work if you want to test
 your  
 client application from the same host, and manually select the
 adapter  
 to use.
 
 - You may use DNS to provide a common name to your server, and access
 it  
 through host name, instead of host address. This probably means some  
 work to get your client domain name, in order to build the complete
 host  
 name in each subnetwork, or be sure that using the host name without
 a  
 domain name will return you the correct host address in all cases.
 
 - In a more complicated fashion, you could decide to convert your  
 service in a standard service, and register it into your DNS
 servers.  
 DNS protocol allows to register the addresses for standard
 services,  
 providing a simplistic discovery service, and allowing you to ask for
 a  
 service name, instead of a host name. AFAIK, this option is not
 usual,  
 but it should work. I am not sure, but you may probably need to use  
 Jakarta commons-net library to perform such kind of queries to your
 DNS  
 server.
 
 - You can delegate the problem to a well-known UDDI server. Anyway,
 if  
 you use TCP/IP, this will just move your problem from one host to  
 another, as this UDDI server/s will probably also have different  
 addresses  in each sub-network.
 
 - You might use some UDP based discovery service. The idea in this
 case  
 would be to send a broadcast message, and receive the appropriate  
 address from some arbitrary point on your network. If you implement
 such  
 a service in your own server, you will probably be able to get the
 host  
 address from the response message meta-data itself. There are some  
 standard libraries for achieving this out there, or you could try to  
 implement your own, as it is plenty of examples on Google ;-)
 
 Hope this helps, 
 Rodrigo
 
 
 Carsten Schmidt wrote: 
  Hi Alain, 
  thanks for your answer, but it seems as if the
 NetworkInterface-class 
  would just be able to give you information about the interfaces. 
   
  For me, it is important to tell the program which Interface to use, 
  because the webserver I'm working on got different IP's in
 different 
  sub-networks. 
   
  So, I am looking for a method like setHostAdress(foo). Maybe this
 is 
  more a part of java than axis, but the Axis-Call-class seems to
 handle 
  the whole hardware/network-stuff on it's own. 
   
  I can't believe that there is no smart way to handle this. 
   
  Carsten 
   
   
  Am Montag, den 15.05.2006, 16:28 +0200 schrieb Pannetier Alain: 
  Hi Carsten, 
  
  Here is an example I use to know whether I'm in the office or at 
  home :   
  
  try {  
  Enumeration myInterfaces = 
  NetworkInterface.getNetworkInterfaces();  
interfaceEnum:  
while ( myInterfaces.hasMoreElements()) {  
NetworkInterface netInterf = (NetworkInterface)  
myInterfaces.nextElement();  
Enumeration addresses = netInterf.getInetAddresses() ;  
while (addresses.hasMoreElements()) {  
InetAddress address = (InetAddress) 
  addresses.nextElement();  
if 
  ( address.getHostAddress().startsWith( OFFICE_PREFIX ) ) {  
isAtTheOffice = true ;  
break interfaceEnum ;  
}  
}  
}  
   } catch (SocketException e) {  
e.printStackTrace();  
   }  
  ... 
  
  It shows how to loop on all your interfaces and select one
 (according 
  to its address prefix...). 
  
  That's probably close to what your're after. 
  
  Alain 
  
  
  -Original Message-  
  From: Schmidt, Carsten -81.01-
 [mailto:[EMAIL PROTECTED]   
  Sent: 15 May 2006 16:17  
  To: axis-user@ws.apache.org  
  Subject: RE: Select the output-network-interface to call an 
  axis-webservice 
  
  Hi,  
  did really no one every had a problem like that?  
  This problem can not be so special, can it? 
  
  But maybe you know another mailinglist or a book, which might be
 able 
  to help me? 
  
  It is really important for me to find a solution for that, and 
  meanwhile I ain't got no more idea where to look at. 
  
  Regards, 
  
  Carsten 
  

  Hi

Re: Select the output-network-interface to call an axis-webservice

2006-05-16 Thread Carsten Schmidt
Hi,
oh, maybe we missunderstood each other.
There is no problem with the IP the service is running on.

On another machine a servlet is calling this service. For this call I
have to determine a special outgoing-IP, because it is a webserver on
which each webapp has it's own virtual-IP.

Only the IP from the app has the necessary permissions to pass the
firewall correctly.

By default the axis-call doesn't use the virtual-IP from the
webapp-context, but the IP from the server itself.

In detail:

Webserver with the IP 10.33.5.1
Virtual IP for the webapp 10.33.5.67

Carsten 




Am Dienstag, den 16.05.2006, 09:47 +0200 schrieb Rodrigo Ruiz:
 Ok,
 
 If you look at the very first example in the users guide:
 
 1   import org.apache.axis.client.Call; 
 2   import org.apache.axis.client.Service; 
 3   import javax.xml.namespace.QName; 
 4 
 5   public class TestClient { 
 6 public static void main(String [] args) { 
 7   try { 
 8 String endpoint = 
 9 http://ws.apache.org:5049/axis/services/echo;; 
 10 
 11Service  service = new Service(); 
 12Call call= (Call) service.createCall(); 
 13 
 14call.setTargetEndpointAddress( new
 java.net.URL(endpoint) ); 
 15call.setOperationName(new QName(http://soapinterop.org/;,  
 echoString)); 
 16 
 17String ret = (String) call.invoke( new Object[]
 { Hello! } ); 
 18 
 19System.out.println(Sent 'Hello!', got ' + ret + '); 
 20  } catch (Exception e) { 
 21System.err.println(e.toString()); 
 22  } 
 23} 
 24  }
 
 You can see that the service endpoint is a URL declared at lines
 8-9.  
 You simply have to build this URL using the host you have read from
 your  
 configuration file.
 
 
 If you are working with generated stubs, you will find that your
 Service  
 class has at least two getPortName() methods (more if you use a  
 WS-Addressing aware generator).
 
 One of these methods gets a URL instance as a parameter. This URL
 must  
 contain the endpoint URL, that is, the same URL you would use in the  
 example above. Therefore, you can again build this URL using your  
 configured host name.
 
 You may allow configuring only a part of your endpoints, like in:
 
 String hostName = myProps.getProperty(hostName); 
 URL url = new URL(http://; + hostName + /axis/services/echo);
 
 or you may get the full endpoint URL from your configuration file,
 like:
 
 String echoEndpoint = myProps.getProperty(Endpoint.Echo); 
 URL url = new URL(echoEndpoint);
 
 I personally think the second option gives you more freedom to
 change  
 your server deployment at will.
 
 HTH, 
 Rodrigo
 
 
 Carsten Schmidt wrote: 
  Hi Rodrigo, 
  these ideas are very interesting. 
   
  First of all, thanks a lot for that. 
   
  But for the first way of making the host address configurable, I
 still 
  have to ask you, how to do that in detail? 
   
  I don't mean how to read the address from a properties file, but how
 can 
  I set the value? 
   
  Carsten 
   
   
  Am Montag, den 15.05.2006, 17:28 +0200 schrieb Rodrigo Ruiz: 
  Carsten, 
  
  In fact, there are several ways to handle your situation, but I 
  guess   
  almost none of them is as simple as adding some lines to your
 client   
  code. The ones I know are: 
  
  - Make the host address configurable. That is, read the host
 address   
  from a configuration file. I know this is not what you are asking 
  for,   
  but it is probably the only easy workaround to your problem. In
 fact, 
  I   
  think it will be the only one that will work if you want to test 
  your   
  client application from the same host, and manually select the 
  adapter   
  to use. 
  
  - You may use DNS to provide a common name to your server, and
 access 
  it   
  through host name, instead of host address. This probably means
 some   
  work to get your client domain name, in order to build the
 complete 
  host   
  name in each subnetwork, or be sure that using the host name
 without 
  a   
  domain name will return you the correct host address in all cases. 
  
  - In a more complicated fashion, you could decide to convert
 your   
  service in a standard service, and register it into your DNS 
  servers.   
  DNS protocol allows to register the addresses for standard 
  services,   
  providing a simplistic discovery service, and allowing you to ask
 for 
  a   
  service name, instead of a host name. AFAIK, this option is not 
  usual,   
  but it should work. I am not sure, but you may probably need to
 use   
  Jakarta commons-net library to perform such kind of queries to
 your 
  DNS   
  server. 
  
  - You can delegate the problem to a well-known UDDI server.
 Anyway, 
  if   
  you use TCP/IP, this will just move your problem from one host
 to   
  another, as this UDDI server/s will probably also have different   
  addresses  in each sub-network. 
  
  - You might use some UDP based discovery service. The idea in this 
  case   
  would

Re: Select the output-network-interface to call an axis-webservice

2006-05-16 Thread Carsten Schmidt
Ok, it is about the communication between two Webservers (with Tomcat as
Servlet Engine).

My local Server provides a Servlet.
Well, it provides lots of Servlets on different tomcats.
Each of these tomcats has its own virtual IP apache listens on.
The server itself has another IP (Which is not used by an application
but to administrate the server).

The servlet calls an axis-service which runs on a completely different
server in another company.

The IP from my server (let's take 10.33.5.1. for example) is not allowed
to access the non-local webservice.
This is not changeable, the reason that for is uninteresting at the
moment.

The only IP, which can access is the one of my servlet (in this case
10.33.5.67).

If I am starting this servlet from my pc (10.33.5.100) it should run
like this:

10.33.5.100 (Browser) - 10.33.5.67 (Tomcat)
10.33.5.67 (Servlet running in Tomcat) - WebService anywhere in the
internet (including the answer, because axis handels this)
10.33.5.67 (Tomcat returns the generated website) - 10.33.5.100
(Browser)

but this way is broken because:

10.33.5.100 (Browser) - 10.33.5.67 (Tomcat)
10.33.5.1 tries to connect the webservice, what is denied by firewall.


With NetworkInterface.getNetworkInterfaces() it shows my all IPs
existing on the server. But it seems as if there was no way of manuelly
choosing which IP to use for an axis-connection.

This topic is awful, I know;-))


Am Dienstag, den 16.05.2006, 13:03 +0200 schrieb Rodrigo Ruiz:
 Wow!
 
 Ok, I guess the solution to your problem will depend on where do you  
 want to set the address. Could you elaborate a bit more?
 
 Are you talking about the client-side or the server-side? I guess
 you  
 are talking about the server response, but I am not sure.
 
 Could you describe a bit your server deployment configuration? Do
 you  
 have a single Axis webapp and you want to customize its behavior  
 depending on the incoming network adapter, or you have separate
 webapps  
 for each virtual-IP?
 
 Regards, 
 Rodrigo
 
 Carsten Schmidt wrote: 
  Hi, 
  oh, maybe we missunderstood each other. 
  There is no problem with the IP the service is running on. 
   
  On another machine a servlet is calling this service. For this call
 I 
  have to determine a special outgoing-IP, because it is a webserver
 on 
  which each webapp has it's own virtual-IP. 
   
  Only the IP from the app has the necessary permissions to pass the 
  firewall correctly. 
   
  By default the axis-call doesn't use the virtual-IP from the 
  webapp-context, but the IP from the server itself. 
   
  In detail: 
   
  Webserver with the IP 10.33.5.1 
  Virtual IP for the webapp 10.33.5.67 
   
  Carsten  
   
   
   
   
  Am Dienstag, den 16.05.2006, 09:47 +0200 schrieb Rodrigo Ruiz: 
  Ok, 
  
  If you look at the very first example in the users guide: 
  
  1   import org.apache.axis.client.Call;  
  2   import org.apache.axis.client.Service;  
  3   import javax.xml.namespace.QName;  
  4  
  5   public class TestClient {  
  6 public static void main(String [] args) {  
  7   try {  
  8 String endpoint =  
  9 http://ws.apache.org:5049/axis/services/echo;;  
  10  
  11Service  service = new Service();  
  12Call call= (Call) service.createCall();  
  13  
  14call.setTargetEndpointAddress( new 
  java.net.URL(endpoint) );  
  15call.setOperationName(new
 QName(http://soapinterop.org/;,   
  echoString));  
  16  
  17String ret = (String) call.invoke( new Object[] 
  { Hello! } );  
  18  
  19System.out.println(Sent 'Hello!', got ' + ret + ');  
  20  } catch (Exception e) {  
  21System.err.println(e.toString());  
  22  }  
  23}  
  24  } 
  
  You can see that the service endpoint is a URL declared at lines 
  8-9.   
  You simply have to build this URL using the host you have read
 from 
  your   
  configuration file. 
  
  
  If you are working with generated stubs, you will find that your 
  Service   
  class has at least two getPortName() methods (more if you use
 a   
  WS-Addressing aware generator). 
  
  One of these methods gets a URL instance as a parameter. This URL 
  must   
  contain the endpoint URL, that is, the same URL you would use in
 the   
  example above. Therefore, you can again build this URL using
 your   
  configured host name. 
  
  You may allow configuring only a part of your endpoints, like in: 
  
  String hostName = myProps.getProperty(hostName);  
  URL url = new URL(http://; + hostName + /axis/services/echo); 
  
  or you may get the full endpoint URL from your configuration file, 
  like: 
  
  String echoEndpoint = myProps.getProperty(Endpoint.Echo);  
  URL url = new URL(echoEndpoint); 
  
  I personally think the second option gives you more freedom to 
  change   
  your server deployment at will. 
  
  HTH,  
  Rodrigo 
  
  
  Carsten Schmidt wrote:  
  Hi Rodrigo,  
  these ideas are very interesting

RE: Select the output-network-interface to call an axis-webservice

2006-05-15 Thread Carsten Schmidt
Hi Alain,
thanks for your answer, but it seems as if the NetworkInterface-class
would just be able to give you information about the interfaces.

For me, it is important to tell the program which Interface to use,
because the webserver I'm working on got different IP's in different
sub-networks.

So, I am looking for a method like setHostAdress(foo). Maybe this is
more a part of java than axis, but the Axis-Call-class seems to handle
the whole hardware/network-stuff on it's own.

I can't believe that there is no smart way to handle this.

Carsten


Am Montag, den 15.05.2006, 16:28 +0200 schrieb Pannetier Alain:
 Hi Carsten,
 
 Here is an example I use to know whether I'm in the office or at
 home :  
 
 try { 
 Enumeration myInterfaces =
 NetworkInterface.getNetworkInterfaces(); 
   interfaceEnum: 
   while ( myInterfaces.hasMoreElements()) { 
   NetworkInterface netInterf = (NetworkInterface) 
   myInterfaces.nextElement(); 
   Enumeration addresses = netInterf.getInetAddresses() ; 
   while (addresses.hasMoreElements()) { 
   InetAddress address = (InetAddress)
 addresses.nextElement(); 
   if
 ( address.getHostAddress().startsWith( OFFICE_PREFIX ) ) { 
   isAtTheOffice = true ; 
   break interfaceEnum ; 
   } 
   } 
   } 
  } catch (SocketException e) { 
   e.printStackTrace(); 
  } 
 ...
 
 It shows how to loop on all your interfaces and select one (according
 to its address prefix...).
 
 That's probably close to what your're after.
 
 Alain
 
 
 -Original Message- 
 From: Schmidt, Carsten -81.01- [mailto:[EMAIL PROTECTED]  
 Sent: 15 May 2006 16:17 
 To: axis-user@ws.apache.org 
 Subject: RE: Select the output-network-interface to call an
 axis-webservice
 
 Hi, 
 did really no one every had a problem like that? 
 This problem can not be so special, can it?
 
 But maybe you know another mailinglist or a book, which might be able
 to help me?
 
 It is really important for me to find a solution for that, and
 meanwhile I ain't got no more idea where to look at.
 
 Regards,
 
 Carsten
 
   
  Hi everybody, 
  maybe this question has already been answered a thousend times, but
 I 
  haven't found anything about it. 
  I got a server with a few different network adapters. Each of them
 with 
  a different IP. Now I'm searching for a way to call a webservice by 
  choosing exacly one of those adapters (which is not the default
 one). 
   
  How can I do than? 
   
  java.net.NetworkInterface shows me what is available, but where can
 it 
  set what to use? org.apache.axis.client.Call? 
  org.apache.axis.client.Service? 
   
  Can anybody help me? 
   
  Carsten