Archived

This forum has been archived. Please start a new discussion on GitHub.

Proxies obtained from a remote object must have their endpoints fully resolved

It happens that any proxy returned through a servant always uses indirect binding if the adapter uses it.

If the caller (the proxy user) and the object adapter share the same registry, everything is fine, but if the caller cannot see the registry, the proxy is left unsable (or bind to an object with the same identity if there is one).

Maybe there is some configuration / design advice to resolve this problem, but i have not been able to find one.

For example, given those slice definitions:
interface MyItf {
void doIt();
};

interface Manager {
MyItf* getMyItf();
};

With those interfaces correctly implemented, consider two networks (A,B) where only two hosts are mutually visible (GwA, GwB). Each gateway runs the Manager servants and bind them to AdparterA and AdapterB object adapters respectively.
Each network uses indirect binding to register its endpoints into an ice registry only accessible inside its network.

Any client application executed inside one of the network (i.e. A) can connect to its Manager and request for a MyItfPrx proxy through the getMyItf() call.
When the MyItfPrx doIt() method is called, the relevant endpoint is resolved and the call succeed.

Now, if we change the configuration file for network B so that the adapter endpoint if forced to bind to a known host/port so that it can be reached from network A, when the myItfB = getMyItf() method is called, the returned proxy only get an indirect endpoint (i.e. like My/Identity @AdapterB).

Any call to myItfB.doIt() method will either succeed or fail depending on the ability for the registry in network A to resolve this proxified string! :confused:

This is counter-intuitive as it is expected that the returned proxy is only bound to the servant that was registered in the remote site, independently of the locator run on the client side.

A workaround, only used to illustrate this dramatic behavior, is to change the Manager interface to return the identity of the created proxy instead of the proxy itself, and let the client ask for the proxy given its fully qualified stringified proxy name.

interface Manager {
string getMyItfIdentity();
};

The identity string returned is used in statements like this:

String ident = aManagerPrx.getMyItfIdentity();
ObjectPrx prx = communicator().stringToProxy(ident+":tcp -h GwB -p 10000");
MyItfPrx myItf = MyItfPrxHelper.checkedCast(prx);

In this case "tcp -h GwB -p 10000" is the endpoint where the Manager on network B can be contacted from network A.

I really thing this is a bug, rather than a misconception, because the endpoint for a returned proxy should really not be resolved based on the client locator, but based on the resolved endpoint of the servant that has created it. :rolleyes:

Regards

Comments

  • benoit
    benoit Rennes, France
    annekat wrote:
    Now, if we change the configuration file for network B so that the adapter endpoint if forced to bind to a known host/port so that it can be reached from network A, when the myItfB = getMyItf() method is called, the returned proxy only get an indirect endpoint (i.e. like My/Identity @AdapterB).

    That's correct, indirect proxies never get transformed into direct proxies. Instead, the Ice client runtime asks the configured locator the endpoints of the adapter when an invocation is done on the indirect proxy. If the locator in the network A doesn't know about AdapterB, it can't return its endpoints.
    annekat wrote:
    Any call to myItfB.doIt() method will either succeed or fail depending on the ability for the registry in network A to resolve this proxified string! :confused:

    This is counter-intuitive as it is expected that the returned proxy is only bound to the servant that was registered in the remote site, independently of the locator run on the client side.

    Do you mean that the returned proxy should be a direct proxy containing the endpoints of the object adapter? You can do exactly this if you don't use the locator :).

    The goal of the locator mechanism is to add an indirection to allow location transparency. It's very similar to the DNS system but instead of mapping host names to IP addresses, the locator mechanism maps adapter IDs to endpoints. Like the DNS system, the locator mechanism relies on a single central registry to store this mapping information.
    annekat wrote:

    I really thing this is a bug, rather than a misconception, because the endpoint for a returned proxy should really not be resolved based on the client locator, but based on the resolved endpoint of the servant that has created it. :rolleyes:

    Regards

    Can you detail a little more why you are using the locator here, perhaps you don't need it? If you don't set the AdapterId property for your object adapter, the proxies created by the object adapter will be direct proxies containing the endpoint information and this should work as you expect. Alternatively, if you need the locator, you could create a direct proxy for your object by using the ObjectAdapter::createDirectProxy(Ice.Identity id) method and return this in the getMyItf() method.

    Benoit.
  • Locator usage still confusing

    I think i understand the logic behind the locator.
    What was not clear to me is how to have a local platform registry (not seen from the outside because i don't want it to be modified by foreign requests) but still have the adapter (maybe one for internal use, and another for external use).

    The internal use of the locator is to discover network services dynamically based on the object type and/or identity.
    But i want external (incoming) connections only able to contact a unique object to allow access filtering, security checks, and so on.

    From your comments, i can do this two ways:

    - not set the AdapterId in the config (but all my objects will be direct proxies)
    - specifically use directProxy() for a subset of objects

    Very nice, just need a better documentation :rolleyes:
  • benoit
    benoit Rennes, France
    Sorry, I'm afraid I don't fully understand what you're trying to do. It sounds like you want to have a facade object that will be used by external clients to contact your backend services. If you don't want the external clients to have to use the locator to locate this facade object, you should register it with a separate object adapter which isn't using the locator (i.e.: you don't define the <adapter name>.AdapterId property for this object adapter). Using a separate object adapter will also allow you to eventually use a secure endpoints (i.e.: IceSSL).

    Let us know if you need more information about this! In the meantime, I'll review the documentation and make the necessary changes to clarify this.

    Benoit.
  • Everything is fine now

    You perfectly caugth my point Benoit,

    We just use the createDirectProxy() method on selected objects.

    The only mistake we made was assuming that the locator is defined for the adapter only if there is an *.Locator property set (the documentation is not explicit about the role of this property and how it relates to the default locator).

    Also, the examples concerning indirect binding where not explicit about the logic behind the locator relationship with the adapter (what happens when there is more than one adapter, differences between a direct / indirect / reverse proxy, ...)

    We enjoy ICE more and more everyday.
  • Ahhh... Indirect Proxies are implicitly created on registered adapters

    Hi Benoit,

    That wasn't apparent to me either. This discussion helped me as well! I look forward to the updated documentation clarifying these issues.

    Regards,
    Ryan