The Properties Facet
On this page:
The PropertiesAdmin
Interface
An administrator may find it useful to be able to view or modify the configuration properties of a remote Ice application. For example, the IceGrid administrative tools allow you to query and update the properties of active servers. The Properties
facet supplies this functionality.
The Ice::PropertiesAdmin
interface provides access to the communicator's configuration properties:
module Ice { interface PropertiesAdmin { string getProperty(string key); PropertyDict getPropertiesForPrefix(string prefix); void setProperties(PropertyDict newProperties); } }
The getProperty
operation retrieves the value of a single property, and the getPropertiesForPrefix
operation returns a dictionary of properties whose keys match the given prefix. These operations have the same semantics as those in the Ice::Properties
interface.
The setProperties
operation merges the entries in newProperties
with the communicator's existing properties. If an entry in newProperties
matches the name of an existing property, that property's value is replaced with the new value. If the new value is an empty string, the property is removed. Any existing properties that are not modified or removed by the entries in newProperties
are retained with their original values. If the Ice.Trace.Admin.Properties
property is enabled, Ice logs a message if a call to setProperties
results in any changes to the property set.
Modifying a program's configuration properties at run time may not have an effect on the program. For example, many of Ice's standard configuration properties are read once during communicator initialization, and never again.
Obtaining the Local Properties Facet
We already showed how to obtain a proxy for a remote administrative facet, but suppose you want to interact with the facet in your local address space. The code below shows the necessary steps:
auto obj = communicator->findAdminFacet("Properties"); if(obj) // May be null if the facet is not enabled { auto facet = std::dynamic_pointer_cast<Ice::PropertiesAdmin>(obj); ... }
com.zeroc.Ice.Object obj = communicator.findAdminFacet("Properties"); if(obj != null) // May be null if the facet is not enabled { facet = (com.zeroc.Ice.PropertiesAdmin)obj; ... }
As shown here, the facet is registered with the name Properties
and a regular language cast is used to downcast the base object type to the PropertiesAdmin
interface.
Property Update Notifications
The Ice run time can notify an application whenever its properties change due to invocations of the setProperties
operation on the PropertiesAdmin
interface. This section describes the native API for receiving property updates.
The Properties
facet object provided by the Ice run time derives from the class NativePropertiesAdmin
:
namespace Ice { class NativePropertiesAdmin { public: virtual ~NativePropertiesAdmin(); virtual std::function<void()> addUpdateCallback(std::function<void(const PropertyDict&)>) = 0; }; }
addUpdateCallback
accepts a function parameter (the update callback) and returns another function. Call this returned function to remove the callback.
The callback receives a dictionary<string, string>
value representing the properties that were added, changed or removed, with removed properties denoted by an entry whose value is an empty string. It is legal for the callback implementation to modify the set of callbacks, and Ice ignores any exceptions it might raise.
The following code demonstrates how to register a callback:
auto obj = communicator->findAdminFacet("Properties"); if(obj) { auto facet = std::dynamic_pointer_cast<Ice::NativePropertiesAdmin>(obj); auto propManager = ... facet->addUpdateCallback([propManager](const Ice::PropertyDict& changes) { propManager->updated(changes); }); }
The Properties
facet object provided by the Ice run time derives from the class NativePropertiesAdmin
:
namespace Ice { class NativePropertiesAdmin : public virtual IceUtil::Shared { public: virtual ~NativePropertiesAdmin(); virtual void addUpdateCallback(const PropertiesAdminUpdateCallbackPtr&) = 0; virtual void removeUpdateCallback(const PropertiesAdminUpdateCallbackPtr&) = 0; }; typedef IceUtil::Handle<NativePropertiesAdmin> NativePropertiesAdminPtr; }
The application must supply an instance of PropertiesAdminUpdateCallback
:
namespace Ice { class PropertiesAdminUpdateCallback : virtual public Ice::LocalObject { public: virtual void updated(const PropertyDict& changes) = 0; }; typedef IceUtil::Handle<PropertiesAdminUpdateCallback> PropertiesAdminUpdateCallbackPtr; }
The updated
method receives a dictionary<string, string>
value representing the properties that were added, changed or removed, with removed properties denoted by an entry whose value is an empty string. It is legal for the updated
implementation to modify the set of callbacks, and Ice ignores any exceptions it might raise.
The following code demonstrates how to register a callback:
Ice::ObjectPtr obj = communicator->findAdminFacet("Properties"); if(obj) { Ice::NativePropertiesAdminPtr facet = Ice::NativePropertiesAdminPtr::dynamicCast(obj); Ice::PropertiesAdminUpdateCallbackPtr myCallback = new ...; facet->addUpdateCallback(myCallback); }
The Properties
facet object provided by the Ice run time derives from the class NativePropertiesAdmin
:
namespace Ice { public interface NativePropertiesAdmin { void addUpdateCallback(System.Action<Dictionary<string, string>> callback); void removeUpdateCallback(System.Action<Dictionary<string, string>> callback); } }
The registered callback method receives a dictionary<string, string>
value representing the properties that were added, changed or removed, with removed properties denoted by an entry whose value is an empty string. It is legal for the callback implementation to modify the set of callbacks, and Ice ignores any exceptions it might raise.
The following code demonstrates how to register a callback:
Ice.Object obj = communicator.findAdminFacet("Properties"); if(obj != null) { Ice.NativePropertiesAdmin facet = obj as Ice.NativePropertiesAdmin; propManager = ...; facet.addUpdateCallback(propManager.updated); }
The Properties
facet object provided by the Ice run time derives from the class NativePropertiesAdmin
:
package com.zeroc.Ice; public interface NativePropertiesAdmin { void addUpdateCallback(java.util.function.Consumer<java.util.Map<String, String>> callback); void removeUpdateCallback(java.util.function.Consumer<java.util.Map<String, String>> callback); }
The registered callback method receives a dictionary<string, string>
value representing the properties that were added, changed or removed, with removed properties denoted by an entry whose value is an empty string. It is legal for the callback implementation to modify the set of callbacks, and Ice ignores any exceptions it might raise.
The following code demonstrates how to register a callback:
com.zeroc.Ice.Object obj = communicator.findAdminFacet("Properties"); if(obj != null) { com.zeroc.Ice.NativePropertiesAdmin facet = (com.zeroc.Ice.NativePropertiesAdmin)obj; propManager = ... facet.addUpdateCallback(changes -> propManager.updated(changes)); }
The Properties
facet object provided by the Ice run time derives from the class NativePropertiesAdmin
:
package Ice; public interface PropertiesAdminUpdateCallback { void updated(java.util.Map<String, String> changes); } public interface NativePropertiesAdmin { void addUpdateCallback(PropertiesAdminUpdateCallback callback); void removeUpdateCallback(PropertiesAdminUpdateCallback callback); }
The registered callback method receives a dictionary<string, string>
value representing the properties that were added, changed or removed, with removed properties denoted by an entry whose value is an empty string. It is legal for the callback implementation to modify the set of callbacks, and Ice ignores any exceptions it might raise.
The following code demonstrates how to register a callback:
Ice.Object obj = communicator.findAdminFacet("Properties"); if(obj != null) { Ice.NativePropertiesAdmin facet = (Ice.NativePropertiesAdmin)obj; Ice.PropertiesAdminUpdateCallback callback = ... facet.addUpdateCallback(callback); }