For Inter-ORB communication, e.g., via
The configuration parameter
erl -orber interceptors "{native, ['myInterceptor']}"
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.
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
Each supplied interceptor must export the following functions:
The operations
Assume we want to create a simple access service which purpose is to:
To restricts the access we use a
new_in_connection(Arg, Host, Port) ->
%% 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
[] ->
%% 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}] ->
{ObjTable, ChecksumModule}
end.
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.
When a new request comes in the first interceptor function to be invoked is
in_request_encoded({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
NewBin = ChecksumModule:remove_checksum(Bin),
{NewBin, Extra}.
If the checksum check fails the
If we want to we can restrict any clients to only use a subset of operations exported by a server:
in_request({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Params, Extra) ->
case ets:lookup(ObjTable, {ObjKey, Op}) of
[] ->
exit("Client tried to invoke illegal operation");
[SomeData] ->
{Params, Extra}
end.
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
out_reply(_, _, _, _, Reply, Extra) ->
{Reply, Extra}.
If the client side ORB expects a checksum to be added to the reply we add it by using:
out_reply_encoded({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
NewBin = ChecksumModule:add_checksum(Bin),
{NewBin, Extra}.
If we manipulate the binary as above the behavior must
be
For outgoing requests the principle is the same. Hence, it is not further described here. The complete interceptor module would look like:
-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) ->
%% 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
[] ->
%% 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}] ->
{ObjTable, ChecksumModule}
end.
new_out_connection(Arg, Host, Port) ->
case ets:lookup(out_access_table, Host) of
[] ->
exit("Access not granted");
[{Host, ObjTable, ChecksumModule}] ->
{ObjTable, ChecksumModule}
end.
in_request_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
NewBin = ChecksumModule:remove_checksum(Bin),
{NewBin, Extra}.
in_request({ObjTable, _}, ObjKey, Ctx, Op, Params, Extra) ->
case ets:lookup(ObjTable, {ObjKey, Op}) of
[] ->
exit("Client tried to invoke illegal operation");
[SomeData] ->
{Params, Extra}
end.
out_reply(_, _, _, _, Reply, Extra) ->
{Reply, Extra}.
out_reply_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
NewBin = ChecksumModule:add_checksum(Bin),
{NewBin, Extra}.
out_request({ObjTable, _}, ObjKey, Ctx, Op, Params, Extra) ->
case ets:lookup(ObjTable, {ObjKey, Op}) of
[] ->
exit("Client tried to invoke illegal operation");
[SomeData] ->
{Params, Extra}
end.
out_request_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
NewBin = ChecksumModule:add_checksum(Bin),
{NewBin, Extra}.
in_reply_encoded({_, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
NewBin = ChecksumModule:remove_checksum(Bin),
{NewBin, Extra}.
in_reply(_, _, _, _, Reply, Extra) ->
{Reply, Extra}.
closed_in_connection(Arg) ->
%% Nothing to clean up.
Arg.
closed_out_connection(Arg) ->
%% Nothing to clean up.
Arg.
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