aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl')
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl721
1 files changed, 721 insertions, 0 deletions
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
new file mode 100644
index 0000000000..f37a97c4a7
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
@@ -0,0 +1,721 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-------------------------------------------------------------------
+%% File : CosNotifyChannelAdmin_EventChannel_impl.erl
+%% Purpose :
+%% Created : 28 Sep 1999
+%%-------------------------------------------------------------------
+
+-module('CosNotifyChannelAdmin_EventChannel_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::EventChannel ------------------
+-export([new_for_consumers/4,
+ new_for_suppliers/4,
+ get_consumeradmin/4,
+ get_supplieradmin/4,
+ get_all_consumeradmins/3,
+ get_all_supplieradmins/3]).
+
+%% Attributes (external)
+-export(['_get_MyFactory'/3,
+ '_get_default_consumer_admin'/3,
+ '_get_default_supplier_admin'/3,
+ '_get_default_filter_factory'/3]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotification::AdminPropertiesAdmin ---
+-export([get_admin/3,
+ set_admin/4]).
+
+%%----- Inherit from CosEventChannelAdmin::EventChannel ------
+-export([for_consumers/3,
+ for_suppliers/3,
+ destroy/3]).
+%%--------------- Internal -----------------------------------
+%%----- Inherit from cosNotificationComm ---------------------
+-export([callAny/5,
+ callSeq/5]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%% Data structures
+-record(state, {myFac,
+ myConsumers = [],
+ defConsumerAdmin,
+ defSupplierAdmin,
+ defConsumerAdminPid,
+ defSupplierAdminPid,
+ defFilterFac,
+ defFilterFacPid,
+ etsR,
+ qosLocal,
+ qosGlobal,
+ admGlobal,
+ options,
+ idCounter = 0,
+ 'MaxQueueLength',
+ 'MaxConsumers',
+ 'MaxSuppliers'}).
+%% Data structures constructors
+-define(get_InitState(My, Fil, FilPid, QoS, LQoS, GA, MQ, MC, MS, O),
+ #state{myFac = My,
+ defFilterFac = Fil,
+ defFilterFacPid = FilPid,
+ etsR = ets:new(oe_ets, [set, protected]),
+ qosLocal = LQoS,
+ qosGlobal = QoS,
+ admGlobal = GA,
+ options = O,
+ 'MaxQueueLength' = MQ,
+ 'MaxConsumers' = MC,
+ 'MaxSuppliers' = MS}).
+
+%% NOTE!!!
+%% When forwarding events, the objects we will contact is ONLY ConsumerAdmins!!
+%% Hence, we will store SupplierAdmins and ConsumerAdmins differently. SupplierAdmins
+%% we store in our ets-table while the ConsumerAdmins will be stored on the local
+%% State.
+
+%% Data structures selectors
+-define(get_supplierAdmins(S), [S#state.defSupplierAdmin|
+ lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_'}))]).
+-define(get_consumerAdmins(S), [{0, S#state.defConsumerAdmin,S#state.defConsumerAdminPid}
+ |S#state.myConsumers]).
+-define(get_allAdmins(S), [S#state.defSupplierAdmin,
+ S#state.defConsumerAdmin|
+ lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_'}))++
+ find_field(S#state.myConsumers, 2)]).
+-define(get_consumerAdmIDs(S), [0|find_field(S#state.myConsumers, 1)]).
+-define(get_supplierAdmIDs(S), [0|lists:flatten(ets:match(S#state.etsR,
+ {'$1','_','_'}))]).
+
+-define(get_supplierAdmin(S, I), find_obj(ets:lookup(S#state.etsR, I))).
+-define(get_consumerAdmin(S, I), find_obj(lists:keysearch(I,1,S#state.myConsumers))).
+-define(get_supplierAmount(S), ets:info(S#state.etsR, size)).
+-define(get_consumerAmount(S), length(S#state.myConsumers)).
+
+-define(get_MyFactory(S), S#state.myFac).
+-define(get_defConsumerAdm(S), S#state.defConsumerAdmin).
+-define(get_defSupplierAdm(S), S#state.defSupplierAdmin).
+-define(get_defConsumerAdmPid(S), S#state.defConsumerAdminPid).
+-define(get_defSupplierAdmPid(S), S#state.defSupplierAdminPid).
+-define(get_defFilterFac(S), S#state.defFilterFac).
+-define(get_defFilterFacPid(S), S#state.defFilterFacPid).
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+-define(get_GlobalAdm(S), S#state.admGlobal).
+-define(get_Options(S), S#state.options).
+-define(get_MaxQueueLength(S), S#state.'MaxQueueLength').
+-define(get_MaxConsumers(S), S#state.'MaxConsumers').
+-define(get_MaxSuppliers(S), S#state.'MaxSuppliers').
+-define(get_IdCounter(S), S#state.idCounter).
+
+%% Data structures modifiers
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+-define(set_GlobalAdm(S,D), S#state{admGlobal=D}).
+-define(set_AllAdminP(S,GD, MQ, MC, MS),
+ S#state{admGlobal=GD,'MaxQueueLength'=MQ,
+ 'MaxConsumers'=MC, 'MaxSuppliers'=MS}).
+-define(set_MaxQueueLength(S,D), S#state{'MaxQueueLength'=D}).
+-define(set_MaxConsumers(S,D), S#state{'MaxConsumers'=D}).
+-define(set_MaxSuppliers(S,D), S#state{'MaxSuppliers'=D}).
+-define(set_defConsumerAdm(S,D,P), S#state{defConsumerAdmin=D, defConsumerAdminPid=P}).
+-define(set_defSupplierAdm(S,D,P), S#state{defSupplierAdmin=D, defSupplierAdminPid=P}).
+-define(set_defFilterFac(S,D,P), S#state{defFilterFac=D, defFilterFacPid=P}).
+-define(add_supplierAdmin(S,I,O,P), ets:insert(S#state.etsR, {I,O,P})).
+-define(add_consumerAdmin(S,I,O,P), S#state{myConsumers= [{I,O,P}|S#state.myConsumers]}).
+-define(del_supplierAdmin(S,I), ets:delete(S#state.etsR, I)).
+-define(del_consumerAdmin(S,I), S#state{myConsumers=
+ lists:keydelete(I, 1,
+ S#state.myConsumers)}).
+-define(del_consumerAdminRef(S,O), S#state{myConsumers=
+ lists:keydelete(O, 2,
+ S#state.myConsumers)}).
+-define(del_AdminPid(S,P), delete_obj(S, P)).
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+%% MISC
+-define(is_UndefDefConsAdm(S), S#state.defConsumerAdmin == undefined).
+-define(is_UndefDefSuppAdm(S), S#state.defSupplierAdmin == undefined).
+-define(is_UndefDefFilterFac(S), S#state.defFilterFac == undefined).
+-define(is_PersistentConnection(S),
+ ?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_PersistentEvent(S),
+ ?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent).
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?DBG("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, _Reason} when ?get_defConsumerAdmPid(State) == Pid ->
+ {noreply, ?set_defConsumerAdm(State, undefined, undefined)};
+ {'EXIT', Pid, _Reason} when ?get_defSupplierAdmPid(State) == Pid ->
+ {noreply, ?set_defSupplierAdm(State, undefined, undefined)};
+ {'EXIT', Pid, _Reason} when ?get_defFilterFacPid(State) == Pid ->
+ {noreply, ?set_defFilterFac(State, undefined, undefined)};
+ {'EXIT', Pid, normal} ->
+ {noreply, ?del_AdminPid(State, Pid)};
+ _Other ->
+ ?DBG("TERMINATED: ~p~n",[_Other]),
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyFac, InitQoS, InitAdmin, LocalQoS, [MaxQ, MaxC, MaxS|_], Options]) ->
+ process_flag(trap_exit, true),
+ SO = 'CosNotification_Common':get_option(server_options, Options,
+ ?not_DEFAULT_SETTINGS),
+
+ ?DBG("CHANNEL INIT STATE:~n~p~n~p~n~p ~p ~p ~p~n~p~n",
+ [InitQoS, InitAdmin, LocalQoS,MaxQ, MaxC, MaxS, Options]),
+
+ %% Both default Admin:s have the unique id 0 (OMG spec, 98-11-01,
+ %% Notification p 148), hence, no need to create a unique id.
+ %% We don't have acces to OE_THIS in this stage so we cannot create the objects
+ %% now, even though the specification states that.
+ %% DefConAdm = 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([0],[]),
+ %% DefSupAdm = 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([0],[]),
+
+ case 'CosNotifyFilter_FilterFactory':oe_create_link([], [{sup_child, true}|SO]) of
+ {ok, Pid, DefFiFac} ->
+ {ok, ?get_InitState(MyFac, DefFiFac, Pid, InitQoS, LocalQoS,
+ InitAdmin, MaxQ, MaxC, MaxS, Options)};
+ Reason ->
+ {stop, Reason}
+ end.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_EventChannel attributes -------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyFactory'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyFactory'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyFactory(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_default_consumer_admin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_default_consumer_admin'(OE_THIS, _OE_FROM, State)
+ when ?is_UndefDefConsAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefConAdm} ->
+ {reply, DefConAdm, ?set_defConsumerAdm(State, DefConAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:_get_default_consumer_admin();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+'_get_default_consumer_admin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_defConsumerAdm(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_default_supplier_admin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_default_supplier_admin'(OE_THIS, _OE_FROM, State)
+ when ?is_UndefDefSuppAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefSupAdm} ->
+ {reply, DefSupAdm, ?set_defSupplierAdm(State, DefSupAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:_get_default_supplier_admin();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+'_get_default_supplier_admin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_defSupplierAdm(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_default_filter_factory'
+%% Type : readonly
+%% Returns :
+%%----------------------------------------------------------
+'_get_default_filter_factory'(_OE_THIS, _OE_FROM, State)
+ when ?is_UndefDefFilterFac(State) ->
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyFilter_FilterFactory':oe_create_link([], [{sup_child, true}|SO]) of
+ {ok, Pid, DefFiFac} ->
+ {reply, DefFiFac, ?set_defFilterFac(State, DefFiFac, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:_get_default_filter_factory();~n"
+ "Unable to create: CosNotifyChannelAdmin_FilterFactory.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+'_get_default_filter_factory'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_defFilterFac(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : new_for_consumers
+%% Arguments: Op - InterFilterGroupOperator: 'AND_OP' | 'OR_OP'
+%% Determines if the Admin:s proxy-children will
+%% use AND or OR when checking Filters.
+%% Returns : ConsAdm
+%% AdminId (out)
+%%-----------------------------------------------------------
+new_for_consumers(OE_THIS, _OE_FROM, State, Op) ->
+ is_admin_limit_reached(?get_MaxConsumers(State), ?get_consumerAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminCo} ->
+ %% Due to different storage, adding a new consumer is NOT done in the
+ %% same way as for suppliers.
+ NewState = ?add_consumerAdmin(State, AdminId, AdminCo, Pid),
+ {reply, {AdminCo, AdminId}, ?set_IdCounter(NewState, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:nef_for_consumers();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : new_for_suppliers
+%% Arguments: Op - InterFilterGroupOperator: 'AND_OP' | 'OR_OP'
+%% Determines if the Admin:s proxy-children will
+%% use AND or OR when checking Filters.
+%% Returns : SuppAdm
+%% AdminId (out)
+%%-----------------------------------------------------------
+new_for_suppliers(OE_THIS, _OE_FROM, State, Op) ->
+ is_admin_limit_reached(?get_MaxSuppliers(State), ?get_supplierAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminSu} ->
+ %% Due to different storage, adding a new supplier is NOT done in the
+ %% same way as for consumers.
+ ?add_supplierAdmin(State, AdminId, AdminSu, Pid),
+ {reply, {AdminSu, AdminId}, ?set_IdCounter(State, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:new_for_suppliers();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : get_consumeradmin
+%% Arguments: AdminId
+%% Returns : ConsAdmin
+%%-----------------------------------------------------------
+get_consumeradmin(OE_THIS, _OE_FROM, State, 0) when ?is_UndefDefConsAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefConAdm} ->
+ {reply, DefConAdm, ?set_defConsumerAdm(State, DefConAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_consumer_admin();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+get_consumeradmin(_OE_THIS, _OE_FROM, State, 0) ->
+ {reply, ?get_defConsumerAdm(State), State};
+get_consumeradmin(_OE_THIS, _OE_FROM, State, AdminId) when is_integer(AdminId) ->
+ {reply, ?get_consumerAdmin(State, AdminId), State};
+get_consumeradmin(_, _, _, What) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_consumeradmin(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_supplieradmin
+%% Arguments: AdminId
+%% Returns :
+%%-----------------------------------------------------------
+get_supplieradmin(OE_THIS, _OE_FROM, State, 0) when ?is_UndefDefSuppAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefSupAdm} ->
+ {reply, DefSupAdm, ?set_defSupplierAdm(State, DefSupAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_supplieradmin();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+get_supplieradmin(_OE_THIS, _OE_FROM, State, 0) ->
+ {reply, ?get_defSupplierAdm(State), State};
+get_supplieradmin(_OE_THIS, _OE_FROM, State, AdminId) when is_integer(AdminId) ->
+ {reply, ?get_supplierAdmin(State, AdminId), State};
+get_supplieradmin(_, _, _, What) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_supplieradmin(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_consumeradmins
+%% Arguments: -
+%% Returns : AdminIDSeq - a list of all unique ID:s.
+%%-----------------------------------------------------------
+get_all_consumeradmins(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_consumerAdmIDs(State), State}.
+
+%%----------------------------------------------------------%
+%% function : get_all_supplieradmins
+%% Arguments: -
+%% Returns : AdminIDSeq - a list of all unique ID:s.
+%%-----------------------------------------------------------
+get_all_supplieradmins(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_supplierAdmIDs(State), State}.
+
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments: -
+%% Returns : CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {GQoS,LQoS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ channel, false,
+ ?get_allAdmins(State)),
+ {reply, ok, ?set_BothQoS(State, GQoS,LQoS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS} |
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ channel, false,
+ ?get_allAdmins(State)),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotification::AdminPropertiesAdmin --
+%%-----------------------------------------------------------%
+%% function : get_admin
+%% Arguments: -
+%% Returns : AdminProperties
+%%-----------------------------------------------------------
+get_admin(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalAdm(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_admin
+%% Arguments: Admin
+%% Returns :
+%%-----------------------------------------------------------
+set_admin(_OE_THIS, _OE_FROM, State, Admin) ->
+ {GAdm,[MaxQ, MaxC, MaxS|_]} =
+ 'CosNotification_Common':set_adm(Admin, ?get_GlobalAdm(State)),
+ {reply, ok, ?set_AllAdminP(State, GAdm, MaxQ, MaxC, MaxS)}.
+
+%%----- Inherit from CosEventChannelAdmin::EventChannel -----
+%%----------------------------------------------------------%
+%% function : for_consumers
+%% Arguments: -
+%% Returns : ConsAdm
+%%-----------------------------------------------------------
+for_consumers(OE_THIS, _OE_FROM, State) ->
+ is_admin_limit_reached(?get_MaxConsumers(State), ?get_consumerAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), 'AND_OP',
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminCo} ->
+ %% Due to different storage, adding a new consumer is NOT done in the
+ %% same way as for suppliers.
+ NewState = ?add_consumerAdmin(State, AdminId, AdminCo, Pid),
+ {reply, AdminCo, ?set_IdCounter(NewState, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:for_consumers();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : for_suppliers
+%% Arguments: -
+%% Returns : SuppAdm
+%%-----------------------------------------------------------
+for_suppliers(OE_THIS, _OE_FROM, State) ->
+ is_admin_limit_reached(?get_MaxSuppliers(State), ?get_supplierAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), 'AND_OP',
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminSu} ->
+ %% Due to different storage, adding a new supplier is NOT done in the
+ %% same way as for consumers.
+ ?add_supplierAdmin(State, AdminId, AdminSu, Pid),
+ {reply, AdminSu, ?set_IdCounter(State, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:for_suppliers();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%-----------------------------------------------------------%
+%% function : destroy
+%% Arguments: -
+%% Returns : ok
+%%------------------------------------------------------------
+destroy(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj([]) -> {'EXCEPTION', #'CosNotifyChannelAdmin_AdminNotFound'{}};
+find_obj([{_, Obj,_}]) -> Obj;
+find_obj({value, {_, Obj,_}}) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyChannelAdmin_AdminNotFound'{}}.
+
+
+find_field(List, Field) ->
+ find_field(List, Field, []).
+
+find_field([], _, Acc) ->
+ Acc;
+find_field([{I,_,_}|T], 1, Acc) ->
+ find_field(T, 1, [I|Acc]);
+find_field([{_,O,_}|T], 2, Acc) ->
+ find_field(T, 2, [O|Acc]);
+% Left out for now to avoid dialyzer warning.
+%find_field([{_,_,P}|T], 3, Acc) ->
+% find_field(T, 3, [P|Acc]);
+find_field(What, _, _) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:find_field();~n"
+ "Data corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+delete_obj(State, Pid) ->
+ case ets:match_object(State#state.etsR, {'_', '_', Pid}) of
+ [] ->
+ State#state{myConsumers=lists:keydelete(Pid, 3, State#state.myConsumers)};
+ [{Id,_Obj,Pid}] ->
+ ets:delete(State#state.etsR, Id),
+ State
+ end.
+
+%% Test if we have reached limit for Admin objects.
+is_admin_limit_reached(0, _) ->
+ %% When set to zero it means that there is no limit.
+ ok;
+is_admin_limit_reached(Max, Current) when Current >= Max ->
+ %% The Current value do not include the default Admin objects, hence
+ %% we use >= instead of >.
+ corba:raise(#'IMP_LIMIT'{completion_status=?COMPLETED_NO});
+is_admin_limit_reached(_, _) ->
+ ok.
+
+%%-----------------------------------------------------------
+%% function : callSeq
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callSeq(_OE_THIS, OE_FROM, State, Event, Status) ->
+ corba:reply(OE_FROM, ok),
+ forward(seq, State, Event, Status).
+
+%%-----------------------------------------------------------
+%% function : callAny
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callAny(_OE_THIS, OE_FROM, State, Event, Status) ->
+ corba:reply(OE_FROM, ok),
+ forward(any, State, Event, Status).
+
+%% Forward events
+forward(Type, State, Event, Status) ->
+ forward(Type, ?get_consumerAdmins(State), State, Event, Status).
+
+forward(_, [], State, _, _) ->
+ {noreply, State};
+forward(Type, [{_,undefined,_}|T], State, Event, Status) ->
+ %% Match if no default objects associated.
+ forward(Type, T, State, Event, Status);
+forward(any, [{_,H,_}|T], State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callAny(H, Event, Status) of
+ ok ->
+ ?DBG("CHANNEL FORWARD ANY: ~p~n",[Event]),
+ forward(any, T, State, Event, Status);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin no longer exists; dropping it: ~p",
+ [?LINE, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State,H),
+ forward(any, T, NewState, Event, Status);
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p/~p",
+ [?LINE, R, H], ?DEBUG_LEVEL),
+ forward(any, T, State, Event, Status);
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p~n"
+ "Dropping it: ~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State, H),
+ forward(any, T, NewState, Event, Status)
+ end;
+forward(seq, [{_,H,_}|T], State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callSeq(H, Event, Status) of
+ ok ->
+ ?DBG("CHANNEL FORWARD SEQUENCE: ~p~n",[Event]),
+ forward(seq, T, State, Event, Status);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin no longer exists; dropping it: ~p",
+ [?LINE, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State,H),
+ forward(seq, T, NewState, Event, Status);
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p/~p",
+ [?LINE, R, H], ?DEBUG_LEVEL),
+ forward(seq, T, State, Event, Status);
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p~n"
+ "Dropping it: ~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State,H),
+ forward(seq, T, NewState, Event, Status)
+ end.
+
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------