cosnotification_common.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,210 行 · 第 1/3 页
ERL
1,210 行
{Val, Val} -> ok; {Val, _} when Val >= ?not_MinPacing, Val =< ?not_MaxPacing -> {ok, Req, LQS}; {Val, _} when integer(Val) -> {unsupported, #'CosNotification_PropertyError'{ code = 'BAD_VALUE', name = Req#'CosNotification_Property'.name, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinPacing), high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxPacing) } } }; _-> {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.%%------------------------------------------------------------%% function : 'MaxEventsPerConsumer'/6%% 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 : %% Effect : %%------------------------------------------------------------'MaxEventsPerConsumer'(Req, _Type, _Curr, _Parent, _Childs, LQS) -> case {any:get_value(Req#'CosNotification_Property'.value), ?not_GetMaxEventsPerConsumer(LQS)} of {Val, Val} -> ok; {Val, _} when integer(Val), Val >= ?not_MinConsumerEvents, Val =< ?not_MaxConsumerEvents -> {ok, Req, LQS}; {Val, _} when integer(Val) -> {unsupported, #'CosNotification_PropertyError'{ code = 'BAD_VALUE', name = Req#'CosNotification_Property'.name, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinConsumerEvents), high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxConsumerEvents) } } }; _-> {unsupported, #'CosNotification_PropertyError'{ code = 'UNSUPPORTED_VALUE', name = Req#'CosNotification_Property'.name, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents), high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents) } } } end.%%------------------------------------------------------------%% function : validate_qos/5%% Arguments: Wanted - requested QoS to be set.%% Curr - current QoS OMG style and LQS, local %% representation of QoS, grouped as {OMGQ, LQS}%% Type - channel | admin | proxy%% Parent - Factory if Channel, Channel if Admin etc%% Childs - Admins if Channel etc%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{}%% case 1 if all supported, case 2 if at least 1 QoS not%% supported.%% See also p59, 2.5.6.4, OMG TC Document telecom/98-11-01. Quote:%% "If the supplied QoS is supported, it returns additional QoS%% properties which could be optionally added as well."%%------------------------------------------------------------validate_qos(Wanted, Curr, Type, Parent, Childs) -> %% If not supported this function will raise an exception, which we should %% not catch, but all we need to is to raise the exception as it is. {_, LQS}=set_qos(Wanted, Curr, Type, Parent, Childs), NewNPR = check_limits(LQS, ?not_QOS_LIMITS), remove_qos(Wanted, LQS, NewNPR).remove_qos([], _, NPR) -> NPR;remove_qos([H|T], LQS, NPR) -> NewNPR=remove(NPR, H#'CosNotification_Property'.name), remove_qos(T, LQS, NewNPR).check_limits(LQS, NPR) -> case {?not_GetEventReliability(LQS), ?not_GetConnectionReliability(LQS), ?not_Persistent, ?not_BestEffort} of {P,P,P,_B} -> New = #'CosNotification_NamedPropertyRange' {name=?not_EventReliability, range= #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:short(), ?not_BestEffort), high_val=any:create(orber_tc:short(), ?not_BestEffort) }}, NewNPR=change(NPR, ?not_EventReliability, New), remove(NewNPR, ?not_ConnectionReliability); {_,B,_P,B} -> remove(NPR, ?not_EventReliability); {B,P,P,B} -> New = #'CosNotification_NamedPropertyRange' {name=?not_ConnectionReliability, range= #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:short(), ?not_BestEffort), high_val=any:create(orber_tc:short(), ?not_BestEffort) }}, change(NPR, ?not_ConnectionReliability, New) end.%%------------------------------------------------------------%% function : validate_event_qos/2%% Arguments: Wanted - requested QoS to be set.%% Curr - LQS, local representation of QoS%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{}%% case 1 if all supported, case 2 if at least 1 QoS not%% supported.%%------------------------------------------------------------validate_event_qos(Wanted, Curr) -> v_e_q_helper(Wanted, Curr, []), [].v_e_q_helper([], _Curr, []) -> %% Parsed all and foynd no conflicts. ok;v_e_q_helper([], _Curr, Unsupp) -> %% Not possible to use these requested QoS. corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});%%--- EventReliability ---%%v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability, value=#any{value=?not_BestEffort}}|T], Curr, Unsupp) -> %% Always ok. v_e_q_helper(T, Curr, Unsupp);v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability, value=#any{value=?not_Persistent}}|T], Curr, Unsupp) when ?not_GetConnectionReliability(Curr) =/= ?not_BestEffort, ?not_GetEventReliability(Curr) =/= ?not_BestEffort, ?not_GetStopTimeSupported(Curr) =/= true -> v_e_q_helper(T, Curr, Unsupp);v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability}|T], Curr, Unsupp) -> %% Impossible to set to Persistent if the connection reliability is best effort. v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'UNAVAILABLE_VALUE', name = ?not_EventReliability, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null)}}|Unsupp]);%%--- Priority ---%%v_e_q_helper([#'CosNotification_Property'{name=?not_Priority, value=#any{value=V}}|T], Curr, Unsupp) -> if ?not_GetOrderPolicy(Curr) =/= ?not_AnyOrder, ?not_GetOrderPolicy(Curr) =/= ?not_Priority, ?not_GetDiscardPolicy(Curr) =/= ?not_Priority -> %% No use setting Priority since it's not currently used. v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'UNAVAILABLE_VALUE', name = ?not_Priority, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null) }}|Unsupp]); V =< ?not_HighestPriority, V >= ?not_LowestPriority -> v_e_q_helper(T, Curr, Unsupp); true -> v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'BAD_VALUE', name = ?not_Priority, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:short(), ?not_LowestPriority), high_val=any:create(orber_tc:short(), ?not_HighestPriority)}}|Unsupp]) end;%%--- StartTime ---%%v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp) when ?not_GetStartTimeSupported(Curr) =/= false, ?not_GetEventReliability(Curr) =/= ?not_Persistent -> v_e_q_helper(T, Curr, Unsupp);v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp) -> v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'UNAVAILABLE_VALUE', name = ?not_StartTime, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null) }}|Unsupp]);%%--- StopTime ---%%v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp) when ?not_GetStopTimeSupported(Curr) =/= false, ?not_GetEventReliability(Curr) =/= ?not_Persistent -> v_e_q_helper(T, Curr, Unsupp);v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp) -> v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'UNAVAILABLE_VALUE', name = ?not_StopTime, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null) }}|Unsupp]);%%--- Timeout ---%%v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp) when ?not_GetStopTimeSupported(Curr) =/= false, ?not_GetEventReliability(Curr) =/= ?not_Persistent -> v_e_q_helper(T, Curr, Unsupp);v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp) -> v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'UNAVAILABLE_VALUE', name = ?not_Timeout, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null) }}|Unsupp]);%%--- Unknown Event QoS ---%%v_e_q_helper([#'CosNotification_Property'{name=Name}|T], Curr, Unsupp) -> %% Unsupported property. v_e_q_helper(T, Curr, [#'CosNotification_PropertyError' {code = 'BAD_PROPERTY', name = Name, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null) }}|Unsupp]);v_e_q_helper(What, _, _) -> %% Not a Property struct. orber:dbg("[~p] CosNotification_Common:v_e_q_helper(~p);~n" "Not a CosNotification_Property struct.", [?LINE, What], ?DEBUG_LEVEL), corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).%%-------------- QOS HELP FUNCTIONS --------------------------%%------------------------------------------------------------%% function : set_properties/9%% Arguments: Wanted - requested QoS to be set.%% Current - current QoS OMG style%% Type - channel | admin | proxy%% Supported - List of supported QoS%% Unsupp - acc%% NewQoS - acc%% Parent - Factory if Channel, Channel if Admin etc%% Childs - Admins if Channel etc%% LQS - local representation of QoS.%% Returns : {NewOMGStyleQoS, NewLocalQoS} | #'CosNotification_UnsupportedQoS'{}%%------------------------------------------------------------set_properties([], Curr, channelAdm, _, [], NewQoS,_,_,LAS) -> merge_properties(NewQoS, Curr, LAS);set_properties([], Curr, _, _, [], NewQoS,_,_,LQS) -> %% set_local_qos and merge_properties are help functions found at the end of QoS %% functions. NewLQS = set_local_qos(NewQoS, LQS), merge_properties(NewQoS, Curr, NewLQS);set_properties([], _, channelAdm, _, Unsupp, _,_,_,_) -> corba:raise(#'CosNotification_UnsupportedAdmin'{admin_err = Unsupp});set_properties([], _, _, _, Unsupp, _,_,_,_) -> corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});set_properties([Req|Tail], Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) -> %% set_values and is_supported are help functions found at the end of QoS %% functions. case set_values(is_supported(Supported, Req), Req, Type, Curr, Parent, Childs,LQS) of {unsupported, U} -> set_properties(Tail, Curr, Type, Supported, [U|Unsupp], NewQoS, Parent, Childs,LQS); {ok, S, NewLQS} -> set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,NewLQS); {ok, S} -> set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,LQS); ok -> set_properties(Tail, Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) end. set_values(unsupported,Req,_,_,_,_,_) -> {unsupported, #'CosNotification_PropertyError'{ code = 'BAD_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) } } };set_values({ok, Func}, Req, Type, Curr, Parent, Childs, LQS) -> ?MODULE:Func(Req, Type, Curr, Parent, Childs, LQS).%% Update OMG style QoS list with new values.merge_properties([], NewCurrQoS, LQS) -> {NewCurrQoS, LQS}; merge_properties([H|T], Curr, LQS) -> merge_properties(T, lists:keyreplace(H#'CosNotification_Property'.name, %% get key. #'CosNotification_Property'.name, %% get index. Curr, H), LQS).%% Is the Property S among our supported QoS? is_supported([], _) -> unsupported;is_supported([{Name, Func}|_], #'CosNotification_Property'{name=Name}) -> {ok, Func};is_supported([_|T], S) -> is_supported(T, S).%% Find matching S-Property from a list of OMG style QoSextract([], _) -> unsupported;extract([H|_T], S) when H#'CosNotification_Property'.name== S#'CosNotification_Property'.name -> {ok, H};extract([_|T], S) -> extract(T,S).%% Find matching Property name from a list of OMG style QoSextract_value([], _) -> unsupported;extract_value([H|_T], Key) when H#'CosNotification_Property'.name== Key -> {ok, any:get_value(H#'CosNotification_Property'.value)};extract_value([_|T], Key) -> extract(T,Key).%% Remove matching S-QoS from a list of OMG style QoSremove(List, Key) -> lists:keydelete(Key, #'CosNotification_NamedPropertyRange'.name, %% get index. List).change(List, Key, New) -> lists:keyreplace(Key, #'CosNotification_NamedPropertyRange'.name, %% get index. List, New).%% Get QoS from supplied objects and check if it's the same as S.check_with_relatives([], S, LQS) -> {ok, S, LQS};check_with_relatives([undefined|T], S, LQS) -> check_with_relatives(T, S, LQS);check_with_relatives([H|T], S, LQS) -> case catch extract('CosNotification_QoSAdmin':get_qos(H), S) of {ok, S} -> check_with_relatives(T, S, LQS); _-> %% Varioues reasons for this case (Object not responding, not supported) {unsupported, #'CosNotification_PropertyError'{ code = 'UNAVAILABLE_PROPERTY', name = S#'CosNotification_Property'.name, available_range = #'CosNotification_PropertyRange'{ low_val=any:create(orber_tc:null(), null), high_val=any:create(orber_tc:null(), null) } } } end.%% Set new values to locally defined representation of QoS. Using this approach is %% necessary since we must state the record-field at compile-time.set_local_qos([], LQS) -> LQS;set_local_qos([#'CosNotification_Property'{name=N,value=V}|T], LQS) -> NewLQS = case N of "EventReliability" -> ?not_SetEventReliability(LQS, any:get_value(V)); "ConnectionReliability" -> ?not_SetConnectionReliability(LQS, any:get_value(V)); "Priority" -> ?not_SetPriority(LQS, any:get_value(V)); "Timeout" -> ?not_SetTimeout(LQS, any:get_value(V)); "OrderPolicy" -> ?not_SetOrderPolicy(LQS, any:get_value(V)); "DiscardPolicy" -> ?not_SetDiscardPolicy(LQS, any:get_value(V)); "MaximumBatchSize" -> ?not_SetMaximumBatchSize(LQS, any:get_value(V)); "PacingInterval" -> ?not_SetPacingInterval(LQS, any:get_value(V)); "StartTimeSupported" -> ?not_SetStartTimeSupported(LQS, any:get_value(V)); "StopTimeSupported" -> ?not_SetStopTimeSupported(LQS, any:get_value(V)); "MaxEventsPerConsumer" -> ?not_SetMaxEventsPerConsumer(LQS, any:get_value(V)) end, set_local_qos(T, NewLQS).%%%%%%%%%%%%%%%%% END QOS FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%--------------- END OF MODULE ------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?