Sophie

Sophie

distrib > Fedora > 17 > i386 > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 1084

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- Orber Interceptors</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/orber-3.6.24.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>orber</strong><br><strong>User's Guide</strong><br><small>Version 3.6.24</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="no" title="The Orber Application" expanded="false">The Orber Application<ul>
<li><a href="ch_contents.html">
              Top of chapter
            </a></li>
<li title="Content Overview"><a href="ch_contents.html#id61214">Content Overview</a></li>
<li title="Brief Description of the User's Guide"><a href="ch_contents.html#id62498">Brief Description of the User's Guide</a></li>
</ul>
</li>
<li id="no" title="Introduction to Orber" expanded="false">Introduction to Orber<ul>
<li><a href="ch_introduction.html">
              Top of chapter
            </a></li>
<li title="Overview"><a href="ch_introduction.html#id64790">Overview</a></li>
</ul>
</li>
<li id="no" title="The Orber Application" expanded="false">The Orber Application<ul>
<li><a href="ch_orber_kernel.html">
              Top of chapter
            </a></li>
<li title="ORB Kernel and IIOP "><a href="ch_orber_kernel.html#id57197">ORB Kernel and IIOP </a></li>
<li title="The Object Request Broker (ORB)"><a href="ch_orber_kernel.html#id63374">The Object Request Broker (ORB)</a></li>
<li title="Internet Inter-Object Protocol (IIOP)"><a href="ch_orber_kernel.html#id65057">Internet Inter-Object Protocol (IIOP)</a></li>
</ul>
</li>
<li id="no" title="Interface Repository" expanded="false">Interface Repository<ul>
<li><a href="ch_ifr.html">
              Top of chapter
            </a></li>
<li title="Interface Repository(IFR)"><a href="ch_ifr.html#id64309">Interface Repository(IFR)</a></li>
</ul>
</li>
<li id="no" title="Installing Orber" expanded="false">Installing Orber<ul>
<li><a href="ch_install.html">
              Top of chapter
            </a></li>
<li title="Installation Process "><a href="ch_install.html#id62824">Installation Process </a></li>
<li title="Configuration"><a href="ch_install.html#id74009">Configuration</a></li>
<li title="Firewall Configuration"><a href="ch_install.html#id76130">Firewall Configuration</a></li>
<li title="Interface Configuration"><a href="ch_install.html#id76571">Interface Configuration</a></li>
</ul>
</li>
<li id="no" title="OMG IDL to Erlang Mapping" expanded="false">OMG IDL to Erlang Mapping<ul>
<li><a href="ch_idl_to_erlang_mapping.html">
              Top of chapter
            </a></li>
<li title="OMG IDL to Erlang Mapping - Overview"><a href="ch_idl_to_erlang_mapping.html#id76788">OMG IDL to Erlang Mapping - Overview</a></li>
<li title="OMG IDL Mapping Elements"><a href="ch_idl_to_erlang_mapping.html#id76811">OMG IDL Mapping Elements</a></li>
<li title="Getting Started"><a href="ch_idl_to_erlang_mapping.html#id76868">Getting Started</a></li>
<li title="Basic OMG IDL Types"><a href="ch_idl_to_erlang_mapping.html#id76929">Basic OMG IDL Types</a></li>
<li title="Template OMG IDL Types and Complex Declarators"><a href="ch_idl_to_erlang_mapping.html#id77470">Template OMG IDL Types and Complex Declarators</a></li>
<li title="Constructed OMG IDL Types"><a href="ch_idl_to_erlang_mapping.html#id77956">Constructed OMG IDL Types</a></li>
<li title="Scoped Names and Generated Files"><a href="ch_idl_to_erlang_mapping.html#id78395">Scoped Names and Generated Files</a></li>
<li title="Typecode, Identity and Name Access Functions"><a href="ch_idl_to_erlang_mapping.html#id78787">Typecode, Identity and Name Access Functions</a></li>
<li title="References to Constants"><a href="ch_idl_to_erlang_mapping.html#id78931">References to Constants</a></li>
<li title="References to Objects Defined in OMG IDL"><a href="ch_idl_to_erlang_mapping.html#id78990">References to Objects Defined in OMG IDL</a></li>
<li title="Exceptions"><a href="ch_idl_to_erlang_mapping.html#id79013">Exceptions</a></li>
<li title="Access to Attributes"><a href="ch_idl_to_erlang_mapping.html#id79046">Access to Attributes</a></li>
<li title="Invocations of Operations"><a href="ch_idl_to_erlang_mapping.html#id79103">Invocations of Operations</a></li>
<li title="Implementing the DB Application"><a href="ch_idl_to_erlang_mapping.html#id79262">Implementing the DB Application</a></li>
<li title="Reserved Compiler Names and Keywords"><a href="ch_idl_to_erlang_mapping.html#id79480">Reserved Compiler Names and Keywords</a></li>
<li title="Type Code Representation"><a href="ch_idl_to_erlang_mapping.html#id80225">Type Code Representation</a></li>
</ul>
</li>
<li id="no" title="CosNaming Service" expanded="false">CosNaming Service<ul>
<li><a href="ch_naming_service.html">
              Top of chapter
            </a></li>
<li title="Overview of the CosNaming Service"><a href="ch_naming_service.html#id80888">Overview of the CosNaming Service</a></li>
<li title="The Basic Use-cases of the Naming Service"><a href="ch_naming_service.html#id81031">The Basic Use-cases of the Naming Service</a></li>
<li title="Interoperable Naming Service"><a href="ch_naming_service.html#id81378">Interoperable Naming Service</a></li>
</ul>
</li>
<li id="no" title="How to use security in Orber" expanded="false">How to use security in Orber<ul>
<li><a href="ch_security.html">
              Top of chapter
            </a></li>
<li title="Security in Orber"><a href="ch_security.html#id82238">Security in Orber</a></li>
</ul>
</li>
<li id="no" title="Orber Stubs/Skeletons" expanded="false">Orber Stubs/Skeletons<ul>
<li><a href="ch_stubs.html">
              Top of chapter
            </a></li>
<li title="Orber Stubs and Skeletons Description"><a href="ch_stubs.html#id82459">Orber Stubs and Skeletons Description</a></li>
</ul>
</li>
<li id="no" title="CORBA System and User Defined Exceptions" expanded="false">CORBA System and User Defined Exceptions<ul>
<li><a href="ch_exceptions.html">
              Top of chapter
            </a></li>
<li title="System Exceptions"><a href="ch_exceptions.html#id83036">System Exceptions</a></li>
<li title="User Defined Exceptions"><a href="ch_exceptions.html#id83473">User Defined Exceptions</a></li>
<li title="Throwing Exceptions"><a href="ch_exceptions.html#id83493">Throwing Exceptions</a></li>
<li title="Catching Exceptions"><a href="ch_exceptions.html#id83525">Catching Exceptions</a></li>
</ul>
</li>
<li id="loadscrollpos" title="Orber Interceptors" expanded="true">Orber Interceptors<ul>
<li><a href="ch_interceptors.html">
              Top of chapter
            </a></li>
<li title="Using Interceptors"><a href="ch_interceptors.html#id83634">Using Interceptors</a></li>
<li title="Interceptor Example"><a href="ch_interceptors.html#id83850">Interceptor Example</a></li>
</ul>
</li>
<li id="no" title="OrberWeb" expanded="false">OrberWeb<ul>
<li><a href="ch_orberweb.html">
              Top of chapter
            </a></li>
<li title="Using OrberWeb"><a href="ch_orberweb.html#id84111">Using OrberWeb</a></li>
<li title="Starting OrberWeb"><a href="ch_orberweb.html#id84699">Starting OrberWeb</a></li>
</ul>
</li>
<li id="no" title="Debugging" expanded="false">Debugging<ul>
<li><a href="ch_debugging.html">
              Top of chapter
            </a></li>
<li title="Tools and FAQ"><a href="ch_debugging.html#id84785">Tools and FAQ</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>11 Orber Interceptors</h1>
   

  <h3><a name="id83634">11.1 
        Using Interceptors</a></h3>
    
    <p>For Inter-ORB communication, e.g., via <span class="code">IIOP</span>, it is possible
      to intercept requests and replies. To be able to use <span class="code">Interceptors</span>
      Orber the configuration parameter <span class="code">interceptors</span> must be defined.</p>

    <h4>Configure Orber to Use Interceptors</h4>
      
      <p>The configuration parameter <span class="code">interceptors</span> must be defined, e.g.,
        as command line option:</p>
      <div class="example"><pre>
erl -orber interceptors "{native, ['myInterceptor']}"
      </pre></div>
      <p>It is possible to use more than one interceptor; simply add them to the
        list and they will be invoked in the same order as they appear in the list.</p>
      <p>One can also active and deactivate an interceptor during
        run-time, but this will only affect currently existing connections. 
        For more information, consult Orber's Reference Manual regarding the
        operations <span class="code">orber:activate_audit_trail/0/1</span> and
        <span class="code">orber:activate_audit_trail/0/1.</span></p>
    

    <h4>Creating Interceptors</h4>
      
      <p>Each supplied interceptor <strong>must</strong> export the following functions:</p>
      <ul>
        <li>
<strong>new_out_connection/3/5</strong> - one of these operations is called when
         a client application calls an object residing on remote ORB.
         If an interceptor exports both versions, arity 3 and 5, which
         operation that will be invoked is Orber internal.</li>
        <li>
<strong>new_in_connection/3/5</strong> - one of these operations is invoked
         when a client side ORB tries to set up a connection to the target ORB.
         If an interceptor exports both versions, arity 3 and 5, which
         operation that will be invoked is Orber internal.</li>
        <li>
<strong>out_request/6</strong> - supplies all request data on the client side
         ORB.</li>
        <li>
<strong>out_request_encoded/6</strong> - similar to <span class="code">out_request</span>
         but the request body is encode.</li>
        <li>
<strong>in_request_encoded/6</strong> - after a new request arrives at the
         target ORB the request data is passed to the interceptor in
         encoded format.</li>
        <li>
<strong>in_request/6</strong> - prior to invoking the operation on the
         target object, the interceptor <span class="code">in_request</span> is called.</li>
        <li>
<strong>out_reply/6</strong> - after the target object replied the
        <span class="code">out_reply</span> operation is called with the result of the object
         invocation.</li>
        <li>
<strong>out_reply_encoded/6</strong> - before sending a reply back to the
         client side ORB this operation is called with the result in 
         encoded format.</li>
        <li>
<strong>in_reply_encoded/6</strong> - after the client side ORB receives
         a reply this function is called with the reply in encoded 
         format.</li>
        <li>
<strong>in_reply/6</strong> - before delivering the reply to the client
         this operation is invoked.</li>
        <li>
<strong>closed_in_connection/1</strong> - when a connection is terminated
         on the client side this function is called.</li>
        <li>
<strong>closed_out_connection/1</strong> - if an outgoing connection is
         terminated this operation will be invoked.</li>
      </ul>
      <p>The operations <span class="code">new_out_connection</span>, <span class="code">new_in_connection</span>, 
        <span class="code">closed_in_connection</span> and <span class="code">closed_out_connection</span> operations
        are only invoked <strong>once</strong> per connection. The remaining operations
        are called, as shown below, for every Request/Reply to/from remote
        CORBA Objects.</p>
      <a name="interceptor_operations"></a>
      <img alt="IMAGE MISSING" src="interceptor_operations.gif"><br>
        <em>Figure
        11.1:
         
        
The Invocation Order of Interceptor Functions.</em>
      
    
  

  <h3><a name="id83850">11.2 
        Interceptor Example</a></h3>
    
    <p>Assume we want to create a simple access service which purpose is to:</p>
    <ul>
      <li>Only allow incoming request from ORB's residing on a certain set of
       nodes.</li>
      <li>Restrict the objects any client may invoke operations on.</li>
      <li>Only allow outgoing requests to call a limited set of external
       ORB's.</li>
      <li>Add a checksum to each binary request/reply body.</li>
    </ul>
    <p>To restricts the access we use a <span class="code">protected</span> and <span class="code">named</span> ets-table
      holding all information. How the ets-table is initiated and maintained
      is implementation specific, but it contain 
      <span class="code">{Node, ObjectTable, ChecksumModule}</span> where <span class="code">Node</span> is used as 
      ets-key, <span class="code">ObjectTable</span> is a reference to another ets-table in which
      we store which objects the clients are allowed to invoke operations on
      and <span class="code">ChecksumModule</span> determines which module we should use to handle
      the checksums. </p>
    <div class="example"><pre>
new_in_connection(Arg, Host, Port) -&gt;
    %% Since we only use one interceptor we do not care about the
    %% input Arg since it is set do undefined by Orber.
    case ets:lookup(in_access_table, Host) of
         [] -&gt;
            %% We may want to log the Host/Port to see if someone tried
            %% to hack in to our system.
            exit("Access not granted");
         [{Host, ObjTable, ChecksumModule}] -&gt;
            {ObjTable, ChecksumModule}
    end.
    </pre></div>
    <p>The returned tuple, i.e., {ObjTable, ChecksumModule}, will be passed
      as the first argument whenever invoking one of the interceptor functions.
      Unless the connection attempt did not fail we are now ready for receiving
      requests from the client side ORB.</p>
    <p>When a new request comes in the first interceptor function to be invoked is
      <span class="code">in_request_encoded</span>. We will remove the checksum from the coded
      request body in the following way:</p>
    <div class="example"><pre>
in_request_encoded({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) -&gt;
    NewBin = ChecksumModule:remove_checksum(Bin),
    {NewBin, Extra}.
    </pre></div>
    <p>If the checksum check fails the <span class="code">ChecksumModule</span> should invoke exit/1.
      But if the check succeeded we are now ready to check if the client-ORB 
      objects are allowed to invoke operations on the target object. Please note,
      it is possible to run both checks in <span class="code">in_request_encoded</span>. Please
      note, the checksum calculation must be relatively fast to ensure a
      good throughput.</p>
    <p>If we want to we can restrict any clients to only use a subset of operations
      exported by a server:</p>
    <div class="example"><pre>
in_request({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Params, Extra) -&gt;
    case ets:lookup(ObjTable, {ObjKey, Op}) of
         [] -&gt;
            exit("Client tried to invoke illegal operation");
         [SomeData] -&gt;
            {Params, Extra}
    end.
    </pre></div>
    <p>At this point Orber are now ready to invoke the operation on the target 
      object. Since we do not care about what the reply is the <span class="code">out_reply</span>
      function do nothing, i.e.:</p>
    <div class="example"><pre>
out_reply(_, _, _, _, Reply, Extra) -&gt;
    {Reply, Extra}.
    </pre></div>
    <p>If the client side ORB expects a checksum to be added to the reply we
      add it by using:</p>
    <div class="example"><pre>
out_reply_encoded({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) -&gt;
    NewBin = ChecksumModule:add_checksum(Bin),
    {NewBin, Extra}.
    </pre></div>
    <div class="warning">
<div class="label">Warning</div>
<div class="content"><p>
      <p>If we manipulate the binary as above the behavior <strong>must</strong>
        be <span class="code">Bin == remove_checksum(add_checksum(Bin))</span>.</p>
    </p></div>
</div>
    <p>For outgoing requests the principle is the same. Hence, it is not further
      described here. The complete interceptor module would look like:</p>
    <div class="example"><pre>

-module(myInterceptor).

%% Interceptor functions.
-export([new_out_connection/3,
     new_in_connection/3,
     closed_in_connection/1,
     closed_out_connection/1,
     in_request_encoded/6,
     in_reply_encoded/6,
     out_reply_encoded/6,
     out_request_encoded/6,
     in_request/6,
     in_reply/6,
     out_reply/6,
     out_request/6]).

new_in_connection(Arg, Host, Port) -&gt;
    %% Since we only use one interceptor we do not care about the
    %% input Arg since it is set do undefined by Orber.
    case ets:lookup(in_access_table, Host) of
         [] -&gt;
            %% We may want to log the Host/Port to see if someone tried
            %% to hack in to our system.
            exit("Access not granted");
         [{Host, ObjTable, ChecksumModule}] -&gt;
            {ObjTable, ChecksumModule}
    end.

new_out_connection(Arg, Host, Port) -&gt;
    case ets:lookup(out_access_table, Host) of
         [] -&gt;
            exit("Access not granted");
         [{Host, ObjTable, ChecksumModule}] -&gt;
            {ObjTable, ChecksumModule}
    end.

in_request_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) -&gt;
    NewBin = ChecksumModule:remove_checksum(Bin),
    {NewBin, Extra}.

in_request({ObjTable, _}, ObjKey, Ctx, Op, Params, Extra) -&gt;
    case ets:lookup(ObjTable, {ObjKey, Op}) of
         [] -&gt;
            exit("Client tried to invoke illegal operation");
         [SomeData] -&gt;
            {Params, Extra}
    end.

out_reply(_, _, _, _, Reply, Extra) -&gt;
    {Reply, Extra}.

out_reply_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) -&gt;
    NewBin = ChecksumModule:add_checksum(Bin),
    {NewBin, Extra}.

out_request({ObjTable, _}, ObjKey, Ctx, Op, Params, Extra) -&gt;
    case ets:lookup(ObjTable, {ObjKey, Op}) of
         [] -&gt;
            exit("Client tried to invoke illegal operation");
         [SomeData] -&gt;
            {Params, Extra}
    end.

out_request_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) -&gt;
    NewBin = ChecksumModule:add_checksum(Bin),
    {NewBin, Extra}.

in_reply_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) -&gt;
    NewBin = ChecksumModule:remove_checksum(Bin),
    {NewBin, Extra}.

in_reply(_, _, _, _, Reply, Extra) -&gt;
    {Reply, Extra}.

closed_in_connection(Arg) -&gt;
    %% Nothing to clean up.
    Arg.

closed_out_connection(Arg) -&gt;
    %% Nothing to clean up.
    Arg.
    </pre></div>
    <div class="note">
<div class="label">Note</div>
<div class="content"><p>
      <p>One can also use interceptors for debugging purposes, e.g.,
        print which objects and operations are invoked with which arguments
        and the outcome of the operation. In conjunction with the configuration
        parameter <span class="code">orber_debug_level</span> it is rather easy to find out what
        went wrong or just to log the traffic.  </p>
    </p></div>
</div>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>