cosnotification_common.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,210 行 · 第 1/3 页

ERL
1,210
字号
%%--------------------------------------------------------------------%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%%--------------------------------------------------------------------%% File    : CosNotification_Common.erl%% Purpose : %% Created : 28 Sep 1999%%---------------------------------------------------------------------module('CosNotification_Common').%%--------------- 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 MISC-export([get_option/3,          create_name/2,          create_name/1,	 create_id/0,	 create_id/1,         is_debug_compiled/0,	 type_check/2,         send_stubborn/5,         create_link/3, 	 disconnect/3, 	 do_disconnect/3,	 notify/1]).%% Internal AdminProperties-export([init_adm/1,	 set_adm/2,	 'MaxQueueLength'/6,	 'MaxConsumers'/6,	 'MaxSuppliers'/6]).%% Internal QoS-export([init_qos/1,	 set_qos/5,	 validate_qos/5,	 validate_event_qos/2,	 'EventReliability'/6,	 'ConnectionReliability'/6,	 'Priority'/6,	 'StartTimeSupported'/6,	 'StopTimeSupported'/6,	 'Timeout'/6,	 'OrderPolicy'/6,	 'DiscardPolicy'/6,	 'MaximumBatchSize'/6,	 'PacingInterval'/6,	 'MaxEventsPerConsumer'/6]).%%--------------- DEFINITIONS OF CONSTANTS -------------------%%--------------- EXTERNAL MISC FUNCTIONS --------------------%%------------------------------------------------------------%% function : create_link%% Arguments: Module - which Module to call%%            Env/ArgList - ordinary oe_create arguments.%% Returns  : %% Exception: %% Effect   : Necessary since we want the supervisor to be a %%            'simple_one_for_one'. Otherwise, using for example,%%            'one_for_one', we have to call supervisor:delete_child%%            to remove the childs startspecification from the %%            supervisors internal state.%%------------------------------------------------------------create_link(Module, Env, ArgList) ->    Module:oe_create_link(Env, ArgList).%%-----------------------------------------------------------%%% function : get_option%% Arguments: %% Returns  : %% Exception: %% Effect   : %%------------------------------------------------------------get_option(Key, OptionList, DefaultList) ->    case lists:keysearch(Key, 1, OptionList) of        {value,{Key,Value}} ->            Value;        _ ->            case lists:keysearch(Key, 1, DefaultList) of                {value,{Key,Value}} ->                    Value;                _->                    {error, "Invalid option"}            end    end.%%-----------------------------------------------------------%%% function : create_name/2%% Arguments: %% Returns  : %% Exception: %% Effect   : %%------------------------------------------------------------create_name(Name,Type) ->    {MSec, Sec, USec} = erlang:now(),    lists:concat(['oe_',node(),'_',Type,'_',Name,'_',MSec, '_', Sec, '_', USec]). %%-----------------------------------------------------------%%% function : create_name/1%% Arguments: %% Returns  : %% Exception: %% Effect   : %%------------------------------------------------------------ create_name(Type) ->    {MSec, Sec, USec} = erlang:now(),    lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]). %%------------------------------------------------------------%% function : create_id/0%% Arguments: - %% Returns  : id (long) =/= 0%%            Both default Admin:s have the unique id 0 (OMG spec, 98-11-01, %%            Notification p 148), hence, we may not return 0.%% Exception: %% Purpose  : Throughout the CosNotification service we use,%%            according to the OMG specification, id:s (long),%%            which must be "unique", to retrieve object references.%%            For example: CosNotifyChannelAdmin::ChannelId/AdminID.%%------------------------------------------------------------create_id(-1) ->    1;create_id( 2147483647) ->    -2147483648;create_id(OldID) ->    OldID+1.create_id() ->    {_A,_B,C}=now(),    C. %%-----------------------------------------------------------%%% function : type_check%% Arguments: Obj  - objectrefernce to test.%%            Mod  - Module which contains typeID/0.%% Returns  : 'ok' or raises exception.%% Effect   : %%------------------------------------------------------------type_check(Obj, Mod) ->    case cosNotificationApp:type_check() of	false ->	    ok;	_ ->	    case catch corba_object:is_a(Obj,Mod:typeID()) of		true ->		    ok;		false ->		    orber:dbg("[~p] CosNotification_Common:type_check(~p);~n"			      "The supplied Object is not or does not inherrit from: ~p", 			      [?LINE, Obj, Mod], ?DEBUG_LEVEL),		    corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO});		{'EXCEPTION', E} ->		    orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n"			      "Failed due to: ~p", 			      [?LINE, Obj, Mod, E], ?DEBUG_LEVEL),		    corba:raise(E);		What ->		    orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n"			      "Failed due to: ~p", 			      [?LINE, Obj, Mod, What], ?DEBUG_LEVEL),		    corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})	    end    end.	%%-----------------------------------------------------------%%% function : notify%% Arguments: Items - [Item]%%            Item - {proxy, IOR} | {client, IOR} | {reason, term()}%% Returns  : 'ok' or raises exception.%% Effect   : %%------------------------------------------------------------notify(Items) ->    case cosNotificationApp:notify() of	false ->	    ok;	Module ->	    catch Module:terminated(Items),	    ok    end.	%%------------------------------------------------------------%% function : send_stubborn%% Arguments: M - module%%            F - function%%            A - arguments%%            MaxR - Maximum no retries%%            Wait - sleep Wait seconds before next try.%% Returns  : see effect%% Exception: %% Effect   : Retries repeatidly untill anything else besides%%            'EXIT', 'COMM_FAILURE' or 'OBJECT_NOT_EXIST'%%------------------------------------------------------------ send_stubborn(M, F, A, MaxR, Wait) when list(A) ->    send_stubborn(M, F, A, MaxR, Wait, 0);send_stubborn(M, F, A, MaxR, Wait) ->    send_stubborn(M, F, [A], MaxR, Wait, 0).send_stubborn(M, F, A, MaxR, _Wait, MaxR) ->    orber:dbg("[~p] CosNotification_Common:send_stubborn( ~p ~p ~p ~p).~n"	      "Failed to deliver the event.~n", [?LINE, M,F,A,MaxR], ?DEBUG_LEVEL),    corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO});send_stubborn(M, F, A, MaxR, Wait, Times) ->    ?debug_print("~p:~p(~p)  # of retries: ~p~n", [M,F,A, Times]),        case catch apply(M,F,A) of        {'EXCEPTION', E} when record(E, 'COMM_FAILURE')->            NewTimes = Times +1,            timer:sleep(Wait),            send_stubborn(M, F, A, MaxR, Wait, NewTimes);        {'EXIT', _} ->            NewTimes = Times +1,            timer:sleep(Wait),            send_stubborn(M, F, A, MaxR, Wait, NewTimes);        Other ->            Other    end.%%-----------------------------------------------------------%%% function : disconnect%% Arguments: Module - one of the interfaces defined in CosEventComm.%%            Function - the appropriate disconnect function.%%            Object - the client object reference.%% Returns  : ok%% Exception: %% Effect   : If the process would try to diconnect itself it could%%            result in a deadlock. Hence, we spawn a new process to do it.%%------------------------------------------------------------disconnect(Module, Function, Object) ->    spawn(?MODULE, do_disconnect, [Module, Function, Object]),    ok.do_disconnect(Module, Function, Object) ->    catch Module:Function(Object),    ?DBG("Disconnect ~p:~p(..).~n", [Module, Function]),    ok. %%------------------------------------------------------------%% function : is_debug_compiled%% Arguments: %% Returns  : %% Exception: %% Effect   : %%------------------------------------------------------------ -ifdef(debug).    is_debug_compiled() -> true.-else.    is_debug_compiled() -> false.-endif. %%------------------------------------------------------------%%--------------- AdminPropertiesAdmin -----------------------%%------------------------------------------------------------%%------------------------------------------------------------%% function : init_adm%% Arguments: Wanted  - requested Admins to be set.%% Returns  : #'CosNotification_UnsupportedAdmin'{} |%%            {NewAdmProperties, [MaxQ, MaxC, MaxS]}%% Effect   : may only be used when creating a channel!!!!!!!!%%------------------------------------------------------------init_adm(Wanted) ->    {NewA,_} = set_properties(Wanted, ?not_DEFAULT_ADMINPROPERTIES, channelAdm, 			      ?not_SUPPORTED_ADMINPROPERTIES, [], [], 			      false, false, false),    {NewA, [extract_value(NewA, ?not_MaxQueueLength),	    extract_value(NewA, ?not_MaxConsumers),	    extract_value(NewA, ?not_MaxSuppliers)]}.set_adm(Wanted, Current) ->    {NewA,_} = set_properties(Wanted, Current, channelAdm, 			      ?not_SUPPORTED_ADMINPROPERTIES, 			      [], [], false, false, false),    {NewA, [extract_value(NewA, ?not_MaxQueueLength),	    extract_value(NewA, ?not_MaxConsumers),	    extract_value(NewA, ?not_MaxSuppliers)]}.'MaxQueueLength'(Req,channelAdm,_, _, _, _) -> admin_ok(Req).'MaxConsumers'(Req,channelAdm,_, _, _, _)->    admin_ok(Req).'MaxSuppliers'(Req,channelAdm,_, _, _, _)->    admin_ok(Req).admin_ok(Req) ->    case any:get_value(Req#'CosNotification_Property'.value) of	Val when integer(Val), Val >= 0 ->	    {ok, Req};	_  ->	    {unsupported, 	     #'CosNotification_PropertyError'{	       code = 'BAD_TYPE', 	       name = Req#'CosNotification_Property'.name,	       available_range = #'CosNotification_PropertyRange'{		 low_val=any:create(orber_tc:null(), null), 		 high_val=any:create(orber_tc:null(), null)		}	      }	    }    end.%%------------------------------------------------------------%%--------------- QOS FUNCTIONS ------------------------------%%------------------------------------------------------------%%------------------------------------------------------------%% function : init_qos%% Arguments: Wanted  - requested QoS to be set.%% Returns  : see set_properties/9%% Effect   : may only be used when creating a channel!!!!!!!!%%------------------------------------------------------------init_qos(Wanted) ->    LQS = set_local_qos(?not_DEFAULT_QOS, ?not_CreateInitQoS()),    set_properties(Wanted, ?not_DEFAULT_QOS, channel, ?not_SUPPORTED_QOS, 		   [], [], false, [], LQS).%%------------------------------------------------------------%% function : set_qos/5%% Arguments: Wanted  - requested QoS to be set.%%            Current - current QoS OMG style%%            LQS     - local representation of QoS.%%            Type    - channel | admin | proxy%%            Parent  - Factory if Channel, Channel if Admin etc%%            Childs  - Admins if Channel etc%% Returns  : see set_properties/9%%------------------------------------------------------------set_qos(Wanted, {Current, LQS}, proxy, Parent, _) ->    set_properties(Wanted, Current, proxy, ?not_SUPPORTED_QOS, [], [], Parent, false,LQS);set_qos(Wanted, {Current, LQS}, admin, Parent, Childs) ->    set_properties(Wanted, Current, admin, ?not_SUPPORTED_QOS, [], [], Parent, Childs,LQS);set_qos(Wanted, {Current, LQS}, channel, _, Childs) ->    set_properties(Wanted, Current, channel, ?not_SUPPORTED_QOS, [], [], false, Childs,LQS).%%------------------------------------------------------------%% function : %% Arguments: Req    - Requested QoS, #'CosNotification_Property'{}%%            Type   - Requestee, channel | admin | proxy%%            Curr   - Current QoS, #'CosNotification_Property'{}%%            Parent - false | ObjRef%%            Childs - false | [ObjRef1, .., ObjRefN]%%            LQS    - #qos{} defined in CosNotification_Definitions.hrl%% Returns  : ok - if requested equal to current value.%%            {ok, Req, LQS} - if new and allowed QoS%%            {unsupported,#'CosNotification_PropertyError'{}} otherwise.%% Effect   : %%------------------------------------------------------------'EventReliability'(Req,channel, _Curr, _Parent, _Childs, LQS) ->    case {any:get_value(Req#'CosNotification_Property'.value),	  ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of	{Val, Val, _, _} ->	    %% Is the value requested.	    ok;	{Val, _, Val, _} ->	    {ok, Req, LQS};	{Val, _, _, Val} ->	    {ok, Req, LQS};	_->	    {unsupported, 	     #'CosNotification_PropertyError'{	       code = 'BAD_TYPE', 	       name = Req#'CosNotification_Property'.name,	       available_range = #'CosNotification_PropertyRange'{		 low_val=any:create(orber_tc:null(), null), 		 high_val=any:create(orber_tc:null(), null)		}	      }	    }    end;'EventReliability'(Req,_,_,_,_,_) ->    %% only valid to set this QoS for channels (or per-event).    {unsupported,      #'CosNotification_PropertyError'{       code = 'UNAVAILABLE_PROPERTY',        name = Req#'CosNotification_Property'.name,       available_range = #'CosNotification_PropertyRange'{	 low_val=any:create(orber_tc:null(), null), 	 high_val=any:create(orber_tc:null(), null)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?