Table of Contents Previous Next
Logo
The Ice Run Time in Detail : 28.10 Proxies
Copyright © 2003-2008 ZeroC, Inc.

28.10 Proxies

The introduction to proxies provided in Section 2.2.2 describes a proxy as a local artifact that makes a remote invocation as easy to use as a regular function call. In fact, processing remote invocations is just one of a proxy’s many responsibilities. A proxy also encapsulates the information necessary to contact the object, including its identity (see Section 28.5) and addressing details such as endpoints (see Section 28.10.3). Proxy methods provide access to configuration and connection information, and act as factories for creating new proxies (see Section 28.10.2). Finally, a proxy initiates the establishment of a new connection when necessary (see Section 33.3).

28.10.1 Obtaining Proxies

An application can obtain a proxy in a number of ways.

Stringified Proxies

The communicator operation stringToProxy creates a proxy from its stringified representation, as shown in the following C++ example:
Ice::ObjectPrx p = communicator‑>stringToProxy("ident:tcp ‑p 5000");
See Appendix D for a description of stringified proxies and Section 28.2 for more information on the stringToProxy operation.

Proxy Properties

Rather than hard-coding a stringified proxy as the previous example demonstrated, an application can gain more flexibility by externalizing the proxy in a configuration property. For example, we can define a property that contains our stringified proxy as follows:
MyApp.Proxy=ident:tcp ‑p 5000
We can use the communicator operation propertyToProxy to convert the property’s value into a proxy, as shown below in Java:
Ice.ObjectPrx p = communicator.propertyToProxy("MyApp.Proxy");
As an added convenience, propertyToProxy allows you to define subordinate properties that configure the proxy’s local settings. The properties below demonstrate this feature:
MyApp.Proxy=ident:tcp ‑p 5000
MyApp.Proxy.PreferSecure=1
MyApp.Proxy.EndpointSelection=Ordered
These additional properties simplify the task of customizing a proxy without the need to change the application’s code. The properties shown above are equivalent to the following statements:
Ice.ObjectPrx p = communicator.stringToProxy("ident:tcp ‑p 5000");
p = p.ice_preferSecure(true);
p = p.ice_endpointSelection(Ice.EndpointSelectionType.Ordered);
The list of supported proxy properties is presented in Section C.9. Note that the communicator prints a warning by default if it does not recognize a subordinate property. You can disable this warning using the property Ice.Warn.UnknownProperties (see Section C.3).
Note that proxy properties can themselves have proxy properties. For example, the following sets the PreferSecure property on the default locator’s router:
Ice.Default.Locator.Router.PreferSecure=1

Factory Methods

As we discuss in Section 28.10.2, proxy factory methods allow you to modify aspects of an existing proxy. Since proxies are immutable, factory methods always return a new proxy if the desired modification differs from the proxy’s current configuration. Consider the following C# example:
Ice.ObjectPrx p = communicator.stringToProxy("...");
p = p.ice_oneway();
ice_oneway is considered a factory method because it returns a proxy configured to use oneway invocations. If the original proxy uses a different invocation mode, the return value of ice_oneway is a new proxy object.
The checkedCast and uncheckedCast methods can also be considered factory methods because they return new proxies that are narrowed to a particular Slice interface. A call to checkedCast or uncheckedCast typically follows the use of other factory methods, as shown below:
Ice.ObjectPrx p = communicator.stringToProxy("...");
Ice.LocatorPrx loc =
    Ice.LocatorPrxHelper.checkedCast(p.ice_secure(true));

Invocations

An application can also obtain a proxy as the result of an Ice invocation. Consider the following Slice definitions:
interface Account { ... };
interface Bank {
    Account* findAccount(string id);
};
Invoking the findAccount operation returns a proxy for an Account object. There is no need to use checkedCast or uncheckedCast on this proxy because it has already been narrowed to the Account interface. The C++ code below demonstrates how to invoke findAccount:
BankPrx bank = ...
AccountPrx acct = bank‑>findAccount(id);
Of course, the application must have already obtained a proxy for the bank object using one of the techniques shown above.

28.10.2 Proxy Methods

Although the core proxy functionality is supplied by a language-specific base class, we can describe the proxy methods in terms of Slice operations as shown below:
bool ice_isA(string id);
void ice_ping();
StringSeq ice_ids();
string ice_id();
int ice_hash();
Communicator ice_getCommunicator();
string ice_toString();
Object* ice_identity(Identity id);
Identity ice_getIdentity();
Object* ice_adapterId(string id);
string ice_getAdapterId();
Object* ice_endpoints(EndpointSeq endpoints);
EndpointSeq ice_getEndpoints();
Object* ice_endpointSelection(EndpointSelectionType t);
EndpointSelectionType ice_getEndpointSelection();
Object* ice_context(Context ctx);
Context ice_getContext();
Object* ice_defaultContext();
Object* ice_facet(string facet);
string ice_getFacet();
Object* ice_twoway();
bool ice_isTwoway();
Object* ice_oneway();
bool ice_isOneway();
Object* ice_batchOneway();
bool ice_isBatchOneway();
Object* ice_datagram();
bool ice_isDatagram();
Object* ice_batchDatagram();
bool ice_isBatchDatagram();
Object* ice_secure(bool b);
bool ice_isSecure();
Object* ice_preferSecure(bool b);
bool ice_isPreferSecure();
Object* ice_compress(bool b);
Object* ice_timeout(int timeout);
Object* ice_router(Router* rtr);
Router* ice_getRouter();
Object* ice_locator(Locator* loc);
Locator* ice_getLocator();
Object* ice_locatorCacheTimeout(int seconds);
int ice_getLocatorCacheTimeout();
Object* ice_collocationOptimized(bool b);
bool ice_isCollocationOptimized();
Object* ice_connectionId(string id);
Connection ice_getConnection();
Connection ice_getCachedConnection();
Object* ice_connectionCached(bool b);
bool ice_isConnectionCached();
These methods can be categorized as follows:
• Remote inspection: methods that return information about the remote object. These methods make remote invocations and therefore accept an optional trailing argument of type Ice::Context (see Section 28.11).
• Local inspection: methods that return information about the proxy’s local configuration.
• Factory: methods that return new proxy instances configured with different features.
Proxies are immutable, so factory methods allow an application to obtain a new proxy with the desired configuration. Factory methods essentially clone the original proxy and modify one or more features of the new proxy.
Many of the factory methods are not supported by fixed proxies. Attempting to invoke one of these methods causes the Ice run time to raise FixedProxyException. See page 16 for a description of fixed proxies and Section 33.7 for additional details.
The core proxy methods are explained in greater detail in Table 28.1.
Returns true if the remote object supports the type indicated by the id argument, otherwise false. This method can only be invoked on a twoway proxy.
Determines whether the remote object is reachable. Does not return a value.
Returns the type ids of the types supported by the remote object. The return value is an array of strings. This method can only be invoked on a twoway proxy.
Returns the type id of the most-derived type supported by the remote object. This method can only be invoked on a twoway proxy.
Returns the communicator that was used to create this proxy.
Returns the identity of the Ice object represented by the proxy.
Returns the proxy’s adapter id, or an empty string if no adapter id is configured.
Returns a sequence of Endpoint objects representing the proxy’s endpoints.
Returns a new proxy having the given selection policy (random or ordered). See Section 33.3.1 for more information.
Returns the endpoint selection policy for the proxy.
Returns a new proxy having the given request context. See Section 28.11 for more information on request contexts.
Returns the request context associated with the proxy. See Section 28.11 for more information on request contexts.
Returns a new proxy having the given facet name. See Chapter 30 for more information on facets.
Returns the name of the facet associated with the proxy, or an empty string if no facet has been set. See Chapter 30 for more information on facets.
Returns true if the proxy uses twoway invocations, otherwise false.
Returns true if the proxy uses oneway invocations, otherwise false.
Returns a new proxy for making batch oneway invocations (see Section 28.15).
Returns true if the proxy uses batch oneway invocations, otherwise false.
Returns true if the proxy uses datagram invocations, otherwise false.
Returns a new proxy for making batch datagram invocations (see Section 28.15).
Returns true if the proxy uses batch datagram invocations, otherwise false.
Returns a new proxy whose endpoints may be filtered depending on the boolean argument. If true, only endpoints using secure transports are allowed, otherwise all endpoints are allowed.
Returns true if the proxy uses only secure endpoints, otherwise false.
Returns a new proxy whose endpoints are filtered depending on the boolean argument. If true, endpoints using secure transports are given precedence over endpoints using non-secure transports. If false, the default behavior gives precedence to endpoints using non-secure transports.
Returns true if the proxy prefers secure endpoints, otherwise false.
Returns a new proxy whose protocol compression capability is determined by the boolean argument. If true, the proxy uses protocol compression if it is supported by the endpoint. If false, protocol compression is never used.
Returns a new proxy with the given timeout value in milliseconds. A value of 1 disables timeouts. See Section 28.12 for more information on timeouts.
Returns a new proxy configured with the given router proxy. See Chapter 39 for more information on routers.
Returns the router that is configured for the proxy (null if no router is configured).
Returns a new proxy with the specified locator. See Chapter 35 for more information on locators.
Returns the locator that is configured for the proxy (null if no locator is configured).
Returns a new proxy with the specified locator cache timeout. When binding a proxy to an endpoint, the run time caches the proxy returned by the locator and uses the cached proxy while the cached proxy has been in the cache for less than the timeout. Proxies older than the timeout cause the run time to rebind via the locator. A value of 0 disables caching entirely, and a value of ‑1 means that cached proxies never expire. The default value is ‑1.
Returns a new proxy configured for collocation optimization. If true, collocated optimizations are enabled. The default value is true.
Returns true if the proxy uses collocation optimization, otherwise false.
Returns a new proxy having the given connection identifier. See Section 33.3.3 for more information.
Returns an object representing the connection used by the proxy. If the proxy is not currently associated with a connection, the Ice run time attempts to establish a connection first. See Section 33.5 for more information.
Returns an object representing the connection used by the proxy, or null if the proxy is not currently associated with a connection. See Section 33.5 for more information.
Enables or disables connection caching for the proxy. See Section 33.3.4 for more information
Returns true if the proxy uses connection caching, otherwise false.

28.10.3 Endpoints

Proxy endpoints are the client-side equivalent of object adapter endpoints (see Section 28.4.6). A proxy endpoint identifies the protocol information used to contact a remote object, as shown in the following example:
tcp ‑h www.zeroc.com ‑p 10000
This endpoint states that an object is reachable via TCP on the host www.zeroc.com and the port 10000.
A proxy must have, or be able to obtain, at least one endpoint in order to be useful. As defined in Section 2.2.2, a direct proxy contains one or more endpoints:
MyObject:tcp ‑h www.zeroc.com ‑p 10000:ssl ‑h www.zeroc.com ‑p 10001
In this example the object with the identity MyObject is available at two separate endpoints, one using TCP and the other using SSL.
If a direct proxy does not contain the h option (that is, no host is specified), the Ice run time uses the value of the Ice.Default.Host property (see Appendix C). If Ice.Default.Host is not defined, the localhost interface is used.
An indirect proxy uses a locator (see Chapter 35) to retrieve the endpoints dynamically. One style of indirect proxy contains an adapter identifier:
MyObject @ MyAdapter
When this proxy requires the endpoints associated with MyAdapter, it requests them from the locator.

28.10.4 Endpoint Filtering

A proxy’s configuration determines how its endpoints are used. For example, a proxy configured for secure communication will only use endpoints having a secure protocol, such as SSL.
The factory functions described in Table 28.2 allow applications to manipulate endpoints indirectly. Calling one of these functions returns a new proxy whose endpoints are used in accordance with the proxy’s configuration.
Selects only endpoints capable of making twoway invocations (e.g., TCP, SSL). For example, this disables datagram endpoints.
Selects only endpoints capable of making reliable oneway invocations (e.g., TCP, SSL). For example, this disables datagram endpoints.
Selects only endpoints capable of making reliable oneway batch invocations (e.g., TCP, SSL). For example, this disables datagram endpoints.
Upon return, the set of endpoints in the new proxy is unchanged from the old one. However, the new proxy’s configuration drives a filtering process that the Ice run time performs during connection establishment, as described in Section 33.3.1.
The factory functions do not raise an exception if they produce a proxy with no viable endpoints. For example, the C++ statement below creates such a proxy:
proxy = comm‑>stringToProxy("id:tcp ‑p 10000")‑>ice_datagram();
It is always possible that a proxy could become viable after additional factory functions are invoked, therefore the Ice run time does not raise an exception until connection establishment is attempted. At that point, the application can expect to receive NoEndpointException if the filtering process eliminates all endpoints.
An application can also create a proxy with a specific set of endpoints using the ice_endpoints factory function, whose only argument is a sequence of Ice::Endpoint objects. At present, an application is not able to create new instances of Ice::Endpoint, but rather can only incorporate instances obtained by calling ice_getEndpoints on a proxy. Note that ice_getEndpoints may return an empty sequence if the proxy has no endpoints, as is the case with an indirect proxy.

28.10.5 Defaults and Overrides

It is important to understand how proxies are influenced by Ice configuration properties and settings. The relevant properties can be classified into two categories: defaults and overrides.

Default Properties

Default properties affect proxies created as the result of an Ice invocation, or by calls to stringToProxy or propertyToProxy. These properties do not influence proxies created by factory methods.
For example, suppose we define the following default property:
Ice.Default.PreferSecure=1
We can verify that the property has the desired affect using the following C++ code:
Ice::ObjectPrx p = communicator‑>stringToProxy(...);
assert(p‑>ice_isPreferSecure());
Furthermore, we can verify that the property does not affect proxies returned by factory methods:
Ice::ObjectPrx p2 = p‑>ice_preferSecure(false);
assert(!p2‑>ice_isPreferSecure());
Ice::ObjectPrx p3 = p2‑>ice_oneway();
assert(!p3‑>ice_isPreferSecure());
The default properties are described in Section C.8.

Override Properties

Defining an override property causes the Ice run time to ignore any equivalent proxy setting and use the override property value instead. For example, consider the following property definition:
Ice.Override.Secure=1
This property instructs the Ice run time to use only secure endpoints, producing the same semantics as calling ice_secure(true) on every proxy. However, the property does not alter the settings of an existing proxy, but rather directs the Ice run time to use secure endpoints regardless of the proxy’s security setting. We can verify that this is the case using the following C++ code:
Ice::ObjectPrx p = communicator‑>stringToProxy(...);
p = p‑>ice_secure(false);
assert(!p‑>ice_isSecure()); // The security setting is retained.
The override properties are described in Section C.8.
Table of Contents Previous Next
Logo