<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/en/2172/18/9/_/styles/combined.css?spaceKey=TOP&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/TOP/Service+Locator+Design">Service Locator Design</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~khunt">Ken Hunt</a>
    </h4>
        <br/>
                         <h4>Changes (19)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h3. Location Query <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">!Service Location Request.jpg|border=1! <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">!ServiceLocator-ServiceLookup.png|border=1! <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >This diagram shows a <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">routing</span> <span class="diff-added-words"style="background-color: #dfd;">consumer</span> service using <span class="diff-added-words"style="background-color: #dfd;">the</span> service <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">discovery</span> <span class="diff-added-words"style="background-color: #dfd;">locator</span> to locate another component based on parameters. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"># The initial steps is to get a proxy to service discovery, this will probably end up being a configuration option somewhere. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;"># The initial steps is to get a proxy to service locator, which is done via Ice configuration file.  <br></td></tr>
            <tr><td class="diff-changed-lines" ># The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">routing</span> <span class="diff-added-words"style="background-color: #dfd;">consumer</span> service populates a <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">ServiceDiscoveryParams</span> <span class="diff-added-words"style="background-color: #dfd;">ServiceLocatorParams</span> class with parameters for what it is looking for. <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"># The routing service then calls the locate method with the above mentioned class. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;"># The consumer service then calls the locate() method passing the above mentioned parameters.  <br></td></tr>
            <tr><td class="diff-changed-lines" ># The ServiceDiscoveryManagementImpl object begins iterating through <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the vector</span> <span class="diff-added-words"style="background-color: #dfd;">its collection</span> of ServiceManagementImpl objects. <br></td></tr>
            <tr><td class="diff-changed-lines" ># The service discovery component calls <span class="diff-changed-words">isSupported<span class="diff-added-chars"style="background-color: #dfd;">()</span></span> on the ServiceManagementImpl object. <br></td></tr>
            <tr><td class="diff-changed-lines" ># The ServiceManagementImpl <span class="diff-changed-words">isSupported<span class="diff-added-chars"style="background-color: #dfd;">()</span></span> implementation performs a basic comparison to see if requested parameters are supported. <br></td></tr>
            <tr><td class="diff-changed-lines" ># If <span class="diff-changed-words">supported<span class="diff-added-chars"style="background-color: #dfd;">,</span></span> the ServiceManagementImpl <span class="diff-changed-words">isSupported<span class="diff-added-chars"style="background-color: #dfd;">()</span></span> implementation finds the parameters comparator using the unique identifier that was given when the ServiceManagementImpl was instantiated. <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"># The service discovery component calls isSupported on the ServiceDiscoveryComparator object. <br># The ServiceDiscoveryComparator isSupported implementation calls the isSupported method on the parameters comparator proxy. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;"># The service locator component calls isSupported() on the registered ServiceLocatorComparator object. <br></td></tr>
            <tr><td class="diff-changed-lines" ># The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">parameters</span> comparator returns a boolean value for whether the parameters are supported or not. <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"># The boolean is passed all the way back to the ServiceDiscoveryManagementImpl object. <br># The service discovery component calls GetService on the ServiceImpl object to get a proxy to the component. <br></td></tr>
            <tr><td class="diff-changed-lines" ># The service <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">discovery</span> <span class="diff-added-words"style="background-color: #dfd;">locator</span> component returns the proxy to the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">routing</span> <span class="diff-added-words"style="background-color: #dfd;">consumer</span> service. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h3. Potential hooks <br> <br>After reviewing the design of the service locator I do not believe there are any places where a hook would logically fit in or influence behavior. The only thing you could really logically do would be to stop a component from being considered. You can&#39;t forcefully tell a component what it can do. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. Conventions <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >When configuring <span class="diff-added-words"style="background-color: #dfd;">the</span> service <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">discovery</span> <span class="diff-added-words"style="background-color: #dfd;">locator</span> in an Ice configuration file for a particular component, there are established ports whose use is recommended. The ServiceLocator proxy is typically bound to port 4411, and the ServiceLocatorManager proxy is typically bound to port 4422. <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h3><a name="ServiceLocatorDesign-Implementation"></a>Implementation</h3>

<p>An implementation of this design is available in the servicediscovery repository.</p>

<h3><a name="ServiceLocatorDesign-Files"></a>Files</h3>

<p>Slice is available <a href="/wiki/download/attachments/2457645/service_discovery.ice?version=4&amp;modificationDate=1279726726404">here</a>.</p>

<h3><a name="ServiceLocatorDesign-Overview"></a>Overview</h3>

<p>The service locator is built around the idea of having services register themselves to a central registry. A comparator can also be registered with the central registry to aid in determining whether a service can handle a request or not. The comparator can be written and deployed in the central registry to reduce the amount of remote calls that need to occur.</p>

<p>When a locate request is received all registered services are iterated and all supported parameters are iterated. If an initial comparison of the requested parameter and supported parameter is successful the comparator is optionally queried to do a more fine grained comparison check. If this is also successful a proxy to the service is returned to the locate request caller.</p>

<h3><a name="ServiceLocatorDesign-Interfaces"></a>Interfaces</h3>

<p>The ServiceLocator interface is implemented by the service locator component and provides a method for a component to locate another component based on parameters.</p>

<p>The ServiceLocatorManagement interface is implemented by the service locator component and is used by components to register their services and parameter comparators.</p>

<p>The ServiceManagement interface is implemented by the service locator component. Each time a service is registered, a proxy to this interface is returned so that the caller can  and is used by components to add discovery parameters that they support, suspend themselves, unsuspend themselves, and unregister. </p>

<p>The ServiceLocatorParamsCompare interface is implemented by parameter comparators and is used by the service locator component to query a comparator to see if given parameters are supported.</p>

<h3><a name="ServiceLocatorDesign-Classes"></a>Classes</h3>

<p>The ServiceLocatorParams class is meant to be used as a concrete class that can be extended with service specific details. The service locator component will do a comparison based on the ServiceLocatorParams passed into locate() or locateAll(), against the ServiceLocatorParams attached to a service via its ServiceManagement interface. If a compareguid was specified when adding the ServiceLocatorParams to the service, it will then pass the ServiceLocatorParams object to the comparator identified by the guid. </p>

<p>The default comparison operation (i.e. the comparison that occurs prior to calling a custom comparator, which is the only comparison made if the compareguid is left empty), works as follows:</p>

<ol>
        <li>The category in the params object is compared against the category of the ServiceLocatorParams object(s) related to a service. If they categories don't match, the comparison always fails.</li>
        <li>If the service in the params object is empty, it is assumed that the locateAll() operation is wanting all services matched. In other words, leaving the service field empty acts as a wildcard on the service field. In a wildcard search on services, the id field of ServiceLocatorParams will be ignored. If the service field is specified, however, the comparison will fail if the service field doesn't match the one provided when the service was added.</li>
        <li>If the category and service fields match, then the id field is compared. Like the service field, if this field is empty, it is treated like a wildcard match.</li>
</ol>


<p>Services commonly define the category in slice for a given type of service. The service field can be defined in the component's Ice configuration file, as is the id. A common usage is for the service to be the name of a replica group, and the id the specific instance names within a replica group. But this is a deployment decision. </p>

<h3><a name="ServiceLocatorDesign-DesignDiagram"></a>Design Diagram</h3>

<p><span class="image-wrap" style=""><img src="/wiki/download/attachments/2457645/ServiceDiscovery.png?version=2&amp;modificationDate=1337278440167" style="border: 1px solid black" /></span></p>

<h3><a name="ServiceLocatorDesign-ServiceRegistration"></a>Service Registration</h3>

<p><span class="image-wrap" style=""><img src="/wiki/download/attachments/2457645/ServiceLocator-ServiceRegistration.png?version=1&amp;modificationDate=1337281363215" style="border: 1px solid black" /></span></p>

<p>This diagram shows a component registering with the service locator component and providing supported parameters.</p>

<ol>
        <li>The initial step is for the component to get a proxy to ServiceLocatorManagement. This is done via Ice configuration file.</li>
        <li>The component calls the addService operation with a proxy to its own service.</li>
        <li>The service locator component instantiates a ServiceManagementImpl object to hold a reference to the service and adds it to a set.</li>
        <li>The service locator component returns a proxy to the ServiceManagement interface to the component so that component can manage the service.</li>
        <li>The component populates a ServiceDiscoveryParams class with supported parameters.</li>
        <li>The component then calls the addDiscoveryParams operation on the ServiceManagement proxy, passing in the above mentioned class and an optional unique identifier for a custom comparator.</li>
        <li>The service locator component attaches the ServiceLocatorParams and optional comparator id to the ServiceManagementImpl.</li>
        <li>The service locator is prepared to handle future queries for the service.</li>
</ol>


<p>The above process is typically handled, in practice, using convenience functions of the base Component class, in an override of the base Component class's preparePrimaryServicesForDiscovery() operation:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>
void Component::preparePrimaryServicesForDiscovery()
{
        mFooServiceRegistration = wrapServiceForRegistration(mFooServicePrx, 
                                                            FooServiceDiscoveryCategory);
        managePrimaryService(mFooServiceRegistration );
}
</pre>
</div></div>

<p>To fill in the ServiceLocatorParams object, the wrapServiceForRegistration() operation will use the category passed in as the second argument, and the service and id fields are filled in based on the component's Ice configuration file. Calling managePrimaryService() allows the base Component class to take responsibility not only for the call to addLocatorParams(), but also for calling suspend(), unsuspend(), and unregister() as needed during the component's lifecycle. </p>

<h3><a name="ServiceLocatorDesign-ComparatorRegistration"></a>Comparator Registration</h3>

<p><span class="image-wrap" style=""><img src="/wiki/download/attachments/2457645/ServiceLocator-ComparatorRegistration+Sequence+Diagram.png?version=1&amp;modificationDate=1337292543546" style="border: 1px solid black" /></span></p>

<p>This diagram shows a parameters comparator registering to the service discovery component.</p>

<ol>
        <li>The initial step is for the component to get a proxy to ServiceLocatorManagement. This is done via the component's Ice configuration file.</li>
        <li>The component then calls the addCompare() method with a unique identifier (guid) for the comparator and a proxy to its own ServiceDiscoveryParamsCompare implementation.</li>
        <li>The service locator instantiates a ServiceDiscoveryComparator object and adds it to a map using the unique identifier.</li>
        <li>The service locator will now use the comparator when a locate() operation is performed and the service was registered with the comparator's guid.</li>
</ol>


<h3><a name="ServiceLocatorDesign-LocationQuery"></a>Location Query</h3>

<p><span class="image-wrap" style=""><img src="/wiki/download/attachments/2457645/ServiceLocator-ServiceLookup.png?version=1&amp;modificationDate=1337292904900" style="border: 1px solid black" /></span></p>

<p>This diagram shows a consumer service using the service locator to locate another component based on parameters.</p>

<ol>
        <li>The initial steps is to get a proxy to service locator, which is done via Ice configuration file.</li>
        <li>The consumer service populates a ServiceLocatorParams class with parameters for what it is looking for.</li>
        <li>The consumer service then calls the locate() method passing the above mentioned parameters.</li>
        <li>The ServiceDiscoveryManagementImpl object begins iterating through its collection of ServiceManagementImpl objects.</li>
        <li>The service discovery component calls isSupported() on the ServiceManagementImpl object.</li>
        <li>The ServiceManagementImpl isSupported() implementation performs a basic comparison to see if requested parameters are supported.</li>
        <li>If supported, the ServiceManagementImpl isSupported() implementation finds the parameters comparator using the unique identifier that was given when the ServiceManagementImpl was instantiated.</li>
        <li>The service locator component calls isSupported() on the registered ServiceLocatorComparator object.</li>
        <li>The comparator returns a boolean value for whether the parameters are supported or not.</li>
        <li>The service locator component returns the proxy to the consumer service.</li>
</ol>


<h3><a name="ServiceLocatorDesign-Conventions"></a>Conventions</h3>

<p>When configuring the service locator in an Ice configuration file for a particular component, there are established ports whose use is recommended. The ServiceLocator proxy is typically bound to port 4411, and the ServiceLocatorManager proxy is typically bound to port 4422.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=TOP">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Service+Locator+Design">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=2457645&revisedVersion=29&originalVersion=28">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Service+Locator+Design?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>