Ok, don't worry, the more awful the more interesting :-D

The quick response for your problem is: it is not possible. A more detailed one could be: it is not possible without developing some custom Axis code. What you are trying to achieve is not easy, and I am afraid Axis implementation does not take it into account.

I will try to put you in context, so you can implement what you need.

Socket Creation
---------------

Socket creation is performed by an implementation of org.apache.axis.components.net.SocketFactory or org.apache.axis.components.net.SecureSocketFactory. The first is for HTTP requests, and the second for HTTPS ones. You must implement a custom implementation of these interfaces, and instruct Axis client classes to use them instead of the default ones.

Your implementation will have to include a constructor that receives a Hashtable as one of its parameters. This Hashtable is supposed to contain configuration options, and it is there where the local binding address for your socket should be looked up.

If you look at the DefaultSocketFactory Axis class, you will find that the actual creation and initialization of the socket is performed in a static method. This means that just subclassing is simply not enough. I recommend you to create a "clone" of this class on your package structure, and modify it to accommodate to your needs.

I pass you a java example of how a low-level socket can be created that binds to a specific local address at the end of this mail.

Transport Options
-----------------

The Hashtable containing the SocketFactory configuration options is passed to the factory instance from the Transport handler. The actual class name can be viewed on the client-config.wsdd file, and it usually is:

<transport name="http"
           pivot="java:org.apache.axis.transport.http.HTTPSender"/>

So, in this case, replacing it by your own implementation is easier.

Mapping Services to Local Bind Addresses
----------------------------------------

You have several options, depending on your needs:

1) If you have a separate webapp per remote service, the local host name to be passed to your custom SocketFactory will be a single static value. In this case, you could add a parameter within the transport tag itself. Something like:

<transport name="http" ...>
  <parameter name="bind.host" value="x.x.x.x"/>
</transport>

This way, the value will be passed to your SocketFactory instance.

2) If you have a webapp having to "speak" to different remote services, you could try to create separate AxisClient instances, each one with a different configuration, so you can use a different instance for each remote service. For each configuration, the approach would be the same as the 1) scenario.

3) Implement a "smart" Socket Factory. If you can create a mapping between remote addresses and local bind addresses (something like a routing table), you could implement this mapping within your SocketFactory implementation. This mapping could be even configurable by specifying it as transport parameters, for example:

<transport name="http" ...>
  <parameter name="map:127.0.0.1" value="127.0.0.1"/>
  <parameter name="map:<remote-address>" value="10.33.5.67"/>
  ...
</transport>

I recommend you the third option, as it is the more flexible one. If you do not add extra complexity, for example, allowing patterns in address mappings, the implementation can be really easy.

I think your scenario is quite reasonable so, could I suggest you to open a JIRA bug report on this? I would be glad to contribute on such an issue :-)

Regards,
Rodrigo


package org.rodrisoft;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * Tests opening a socket through a specific local address.
 *
 * @author <a href="mailto:[EMAIL PROTECTED]">Rodrigo Ruiz Aguayo</a>
 * @version 1.0
 */
public class LocalAddressSocketTest {

  /**
   * Main method.
   *
   * @param args Not used
   * @throws Exception If an error occurs
   */
  public static void main(String[] args) throws Exception {

    String remoteHost = "127.0.0.1";
    String localHost = "127.0.0.1";

    switch (args.length) {
      case 2: remoteHost = args[1];
      case 1: localHost = args[0];
      default:
        break;
    }

    Socket socket = new Socket();

    try {
      socket.bind(new InetSocketAddress(localHost, 0));
      socket.connect(new InetSocketAddress(remoteHost, 8080));

      OutputStream os = socket.getOutputStream();
      PrintWriter out = new PrintWriter(os);
      out.println("GET /index.jsp HTTP/1.1");
      out.println("Host: " + remoteHost);
      out.println();
      out.println();
      out.flush();

      InputStream is = socket.getInputStream();
      BufferedReader in = new BufferedReader(new InputStreamReader(is));
      String line = in.readLine();
      while (line != null) {
        System.out.println(line);
        line = in.readLine();
      }
    } finally {
      socket.close();
    }
  }
}


Carsten Schmidt wrote:
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;-))


--
-------------------------------------------------------------------
GRIDSYSTEMS                    Rodrigo Ruiz Aguayo
Parc Bit - Son Espanyol
07120 Palma de Mallorca        mailto:[EMAIL PROTECTED]
Baleares - EspaƱa              Tel:+34-971435085 Fax:+34-971435082
http://www.gridsystems.com
-------------------------------------------------------------------


--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.392 / Virus Database: 268.5.6/339 - Release Date: 14/05/2006

Reply via email to