Skip to content

Commit

Permalink
Merge pull request #1351 from 2600hz/rating_routing
Browse files Browse the repository at this point in the history
Rating and limits preso
  • Loading branch information
lazedo committed Oct 5, 2015
2 parents 90f844e + 6d87c20 commit 2911e5d
Show file tree
Hide file tree
Showing 19 changed files with 475 additions and 101 deletions.
10 changes: 0 additions & 10 deletions applications/crossbar/doc/limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ The version 2 will respond with a "402 - accept charges" first. You will then ne
"data": {
"twoway_trunks": 0,
"inbound_trunks": 11,
"id": "limits",
"ui_metadata": {
"version": "v3.19_s3",
"ui": "monster-ui"
},
"allow_prepay": true,
"outbound_trunks": 5
}
Expand All @@ -101,11 +96,6 @@ The version 2 will respond with a "402 - accept charges" first. You will then ne
"data": {
"twoway_trunks": 0,
"inbound_trunks": 11,
"id": "limits",
"ui_metadata": {
"version": "v3.19_s3",
"ui": "monster-ui"
},
"allow_prepay": true,
"outbound_trunks": 5
},
Expand Down
2 changes: 1 addition & 1 deletion applications/crossbar/priv/couchdb/schemas/acls.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"type": "string"
},
"network-list-name": {
"description": "The trusted list should represent anything that can issue calls without authorization. The authoritative list should indicate inter-network routing equipment (SBC, ect).",
"description": "The trusted list should represent anything that can issue calls without authorization. The authoritative list should indicate inter-network routing equipment (SBC, etc).",
"enum": [
"authoritative",
"trusted"
Expand Down
2 changes: 1 addition & 1 deletion applications/ecallmgr/src/ecallmgr_fs_authn.erl
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ query_registrar(Realm, Username, Node, Id, Method, Props) ->

%% NOTE: Kamailio needs registrar errors since it is blocking with no
%% timeout (at the moment) but when we seek auth for INVITEs we need
%% to wait for conferences, ect. Since Kamailio does not honor
%% to wait for conferences, etc. Since Kamailio does not honor
%% Defer-Response we can use that flag on registrar errors
%% to queue in Kazoo but still advance Kamailio, just need to check here.
-spec maybe_defered_error(ne_binary(), ne_binary(), wh_json:object()) -> {'ok', wh_json:object()} | {'error', 'timeout'}.
Expand Down
4 changes: 3 additions & 1 deletion applications/ecallmgr/src/ecallmgr_fs_authz.erl
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ authorize_reseller(JObj, Props, CallId, Node) ->
lager:debug("call authorized by reseller ~s as ~s", [ResellerId, Type]),
P = props:set_values([{?GET_CCV(<<"Reseller-ID">>), ResellerId}
,{?GET_CCV(<<"Reseller-Billing">>), Type}
], Props),
]
,Props
),
rate_call(P, CallId, Node)
end.

Expand Down
3 changes: 2 additions & 1 deletion applications/hotornot/src/hon_rater.erl
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ get_rate_data(JObj, ToDID, FromDID, Rates) ->
,[wh_json:get_value(<<"rate_name">>, Rate)
,FromDID
,ToDID
]),
]
),
{'ok', rate_resp(Rate, JObj)}
end.

Expand Down
21 changes: 14 additions & 7 deletions applications/hotornot/src/hon_util.erl
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,21 @@ find_candidate_rates(E164, _FromDID) when byte_size(E164) > ?MIN_PREFIX_LEN ->
Keys = build_keys(E164),

lager:debug("searching for prefixes for ~s: ~p", [E164, Keys]),
case couch_mgr:get_results(?WH_RATES_DB, <<"rates/lookup">>, [{'keys', Keys}
,'include_docs'
])
case couch_mgr:get_results(?WH_RATES_DB
,<<"rates/lookup">>
,[{'keys', Keys}
,'include_docs'
]
)
of
{'ok', []}=OK -> OK;
{'error', _}=E -> E;
{'ok', ViewRows} ->
{'ok', [wh_json:get_value(<<"doc">>, ViewRow) || ViewRow <- ViewRows]};
{'error', _}=E -> E
{'ok'
,[wh_json:get_value(<<"doc">>, ViewRow)
|| ViewRow <- ViewRows
]
}
end;
find_candidate_rates(DID, _) ->
lager:debug("DID ~s is too short", [DID]),
Expand Down Expand Up @@ -130,8 +137,8 @@ matching_options(Rate, RouteOptions) ->
options_match([], []) -> 'true';
options_match([], _) -> 'true';
options_match(RateOptions, RouteOptions) ->
lists:all(fun(RouteOpt) ->
props:get_value(RouteOpt, RateOptions, 'false') =/= 'false'
lists:all(fun(RouteOption) ->
props:get_value(RouteOption, RateOptions, 'false') =/= 'false'
end
,RouteOptions
).
24 changes: 14 additions & 10 deletions applications/jonny5/src/j5_allotments.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,19 @@ maybe_consume_allotment(Allotment, Request, Limits) ->
case allotment_consumed_so_far(Allotment, Limits) of
{'error', _R} when GroupConsumed > (Amount - Minimum) ->
lager:debug("account ~s has used all ~ws of their allotment"
,[AccountId, Amount]),
,[AccountId, Amount]
),
Request;
{'error', _R} -> Request;
Consumed when (Consumed + GroupConsumed) > (Amount - Minimum) ->
lager:debug("account ~s has used all ~ws of their allotment"
,[AccountId, Amount]),
,[AccountId, Amount]
),
Request;
Consumed ->
lager:debug("account ~s has ~ws remaining of their allotment"
,[AccountId, Amount - Consumed - GroupConsumed]),
,[AccountId, Amount - Consumed - GroupConsumed]
),
Classification = wh_json:get_value(<<"classification">>, Allotment),
j5_request:authorize(<<"allotment_", Classification/binary>>, Request, Limits)
end.
Expand Down Expand Up @@ -102,7 +105,8 @@ reconcile_allotment(Seconds, Allotment, Request, Limits) ->
Timestamp = wh_util:current_tstamp(),
Id = <<CallId/binary, "-allotment-consumption">>,
lager:debug("adding allotment debit ~s to ledger ~s for ~wsec"
,[Id, LedgerDb, Seconds]),
,[Id, LedgerDb, Seconds]
),
Props =
props:filter_undefined(
[{<<"_id">>, Id}
Expand Down Expand Up @@ -150,9 +154,8 @@ find_allotment_by_classification(Direction, Classification, Limits) ->
find_allotment_by_classification(Classification, Limits) ->
Allotments = j5_limits:allotments(Limits),
lager:debug("checking if account ~s has any allotments for ~s"
,[j5_limits:account_id(Limits)
,Classification
]),
,[j5_limits:account_id(Limits), Classification]
),
case wh_json:get_value(Classification, Allotments) of
'undefined' -> 'undefined';
Allotment -> wh_json:set_value(<<"classification">>, Classification, Allotment)
Expand Down Expand Up @@ -191,13 +194,14 @@ allotment_consumed_so_far(CycleStart, CycleEnd, Classification, Limits, Attempts
,{'reduce', 'false'}
],
case couch_mgr:get_results(LedgerDb, <<"allotments/consumed">>, ViewOptions) of
{'ok', JObjs} -> sum_allotment_consumed_so_far(JObjs, CycleStart);
{'error', 'not_found'} ->
add_transactions_view(LedgerDb, CycleStart, CycleEnd, Classification, Limits, Attempts);
{'error', _R}=Error ->
lager:debug("unable to get consumed quanity for ~s allotment from ~s: ~p"
,[Classification, LedgerDb, _R]),
Error;
{'ok', JObjs} -> sum_allotment_consumed_so_far(JObjs, CycleStart)
,[Classification, LedgerDb, _R]
),
Error
end.

-spec sum_allotment_consumed_so_far(wh_json:objects(), non_neg_integer()) -> non_neg_integer().
Expand Down
63 changes: 38 additions & 25 deletions applications/jonny5/src/j5_authz_req.erl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ determine_account_id(Request) ->
j5_request:deny_account(<<"disabled">>, R)
);
{'error', _R} ->
lager:debug("unable to determine account id for ~s: ~p", [Number, _R]),
lager:debug("unable to determine account id for ~s: ~p"
,[Number, _R]
),
'ok'
end.

Expand Down Expand Up @@ -89,11 +91,12 @@ maybe_account_limited(Request) ->
Limits = j5_limits:get(AccountId),
R = maybe_authorize(Request, Limits),
case j5_request:is_authorized(R, Limits) of
'true' -> maybe_determine_reseller_id(R);
'false' ->
lager:debug("account ~s is not authorized to create this channel"
,[AccountId]),
send_response(R);
'true' -> maybe_determine_reseller_id(R)
,[AccountId]
),
send_response(R)
end.

-spec maybe_determine_reseller_id(j5_request:request()) -> 'ok'.
Expand Down Expand Up @@ -121,24 +124,28 @@ maybe_reseller_limited(Request) ->
j5_request:authorize_reseller(<<"limits_disabled">>, Request)
);
'false' ->
Limits = j5_limits:get(ResellerId),
R = maybe_authorize(Request, Limits),
case j5_request:is_authorized(R, Limits) of
'false' ->
lager:debug("reseller ~s is not authorized to create this channel"
,[ResellerId]),
send_response(R);
'true' -> send_response(R)
end
check_reseller_limits(Request, ResellerId)
end.

-spec maybe_authorize(j5_request:request(), j5_limits:limits()) -> j5_request:request().
-spec check_reseller_limits(j5_request:request(), ne_binary()) -> 'ok'.
check_reseller_limits(Request, ResellerId) ->
Limits = j5_limits:get(ResellerId),
R = maybe_authorize(Request, Limits),
(not j5_request:is_authorized(R, Limits))
andalso lager:debug("reseller ~s is not authorized to create this channel"
,[ResellerId]
),
send_response(R).

-spec maybe_authorize(j5_request:request(), j5_limits:limits()) ->
j5_request:request().
maybe_authorize(Request, Limits) ->
case j5_limits:enabled(Limits) of
'true' -> maybe_authorize_exception(Request, Limits);
'false' ->
lager:debug("limits are disabled for account ~s"
,[j5_limits:account_id(Limits)]),
,[j5_limits:account_id(Limits)]
),
j5_request:authorize(<<"limits_disabled">>, Request, Limits)
end.

Expand All @@ -147,10 +154,10 @@ maybe_authorize_exception(Request, Limits) ->
CallDirection = j5_request:call_direction(Request),
case j5_request:classification(Request) of
<<"emergency">> ->
lager:debug("allowing emergency call", []),
lager:debug("allowing emergency call"),
j5_request:authorize(<<"limits_disabled">>, Request, Limits);
<<"tollfree_us">> when CallDirection =:= <<"outbound">> ->
lager:debug("allowing outbound tollfree call", []),
lager:debug("allowing outbound tollfree call"),
j5_request:authorize(<<"limits_disabled">>, Request, Limits);
_Else -> maybe_hard_limit(Request, Limits)
end.
Expand All @@ -175,8 +182,12 @@ authorize(Request, Limits) ->
'false' -> F(R, Limits);
'true' -> R
end
end, Request, Routines)
,Limits).
end
,Request
,Routines
)
,Limits
).

-spec maybe_soft_limit(j5_request:request(), j5_limits:limits()) -> j5_request:request().
maybe_soft_limit(Request, Limits) ->
Expand All @@ -194,7 +205,7 @@ maybe_outbound_soft_limit(Request, Limits) ->
case j5_limits:soft_limit_outbound(Limits) of
'false' -> Request;
'true' ->
lager:debug("outbound channel authorization is not enforced (soft limit)", []),
lager:debug("outbound channel authorization is not enforced (soft limit)"),
j5_request:set_soft_limit(Request)
end.

Expand All @@ -203,7 +214,7 @@ maybe_inbound_soft_limit(Request, Limits) ->
case j5_limits:soft_limit_inbound(Limits) of
'false' -> Request;
'true' ->
lager:debug("inbound channel authorization is not enforced (soft limit)", []),
lager:debug("inbound channel authorization is not enforced (soft limit)"),
j5_request:set_soft_limit(Request)
end.

Expand All @@ -224,17 +235,19 @@ maybe_get_outbound_flags(AuthType, AuthId, AccountDb) ->
send_response(Request) ->
ServerId = j5_request:server_id(Request),
AccountDb = wh_util:format_account_id(j5_request:account_id(Request), 'encoded'),
AuthType = wh_json:get_value(<<"Authorizing-Type">>, j5_request:ccvs(Request)),
AuthType = wh_json:get_value(<<"Authorizing-Type">>, j5_request:ccvs(Request)),
AuthId = wh_json:get_value(<<"Authorizing-ID">>, j5_request:ccvs(Request)),

OutboundFlags = maybe_get_outbound_flags(AuthType, AuthId, AccountDb),

CCVs = wh_json:from_list(
props:filter_undefined(
[{<<"Account-Trunk-Usage">>, trunk_usage(j5_request:account_id(Request))}
,{<<"Reseller-Trunk-Usage">>, trunk_usage(j5_request:reseller_id(Request))}
,{<<"Outbound-Flags">>, OutboundFlags}
])),
,{<<"Reseller-Trunk-Usage">>, trunk_usage(j5_request:reseller_id(Request))}
,{<<"Outbound-Flags">>, OutboundFlags}
]
)
),

Resp = props:filter_undefined(
[{<<"Is-Authorized">>, wh_util:to_binary(j5_request:is_authorized(Request))}
Expand Down
21 changes: 15 additions & 6 deletions applications/jonny5/src/j5_flat_rate.erl
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ authorize(Request, Limits) ->
case eligible_for_flat_rate(Request) of
'true' ->
lager:debug("checking if account ~s has available flat rate trunks"
,[j5_limits:account_id(Limits)]),
,[j5_limits:account_id(Limits)]
),
maybe_consume_flat_rate(Request, Limits);
'false' ->
lager:debug("number '~s' is not eligible for flat rate trunks", [j5_request:number(Request)]),
lager:debug("number '~s' is not eligible for flat rate trunks"
,[j5_request:number(Request)]
),
Request
end.

Expand All @@ -61,9 +64,13 @@ eligible_for_flat_rate(Request) ->
Number = wnm_util:to_e164(j5_request:number(Request)),
TrunkWhitelist = ?WHITELIST,
TrunkBlacklist = ?BLACKLIST,
(wh_util:is_empty(TrunkWhitelist) orelse re:run(Number, TrunkWhitelist) =/= nomatch)
(wh_util:is_empty(TrunkWhitelist)
orelse re:run(Number, TrunkWhitelist) =/= 'nomatch'
)
andalso
(wh_util:is_empty(TrunkBlacklist) orelse re:run(Number, TrunkBlacklist) =:= nomatch).
(wh_util:is_empty(TrunkBlacklist)
orelse re:run(Number, TrunkBlacklist) =:= 'nomatch'
).

%%--------------------------------------------------------------------
%% @private
Expand Down Expand Up @@ -161,10 +168,12 @@ consume_limit(Limit, Used, Type) ->
case Used - Limit of
Remaining when Remaining > 0 ->
lager:debug("all ~p ~s trunks consumed leaving ~p channels unaccounted for"
,[Limit, Type, Remaining]),
,[Limit, Type, Remaining]
),
Remaining;
_Else ->
lager:debug("account is consuming ~p/~p ~s trunks"
,[Used - 1, Limit, Type]),
,[Used - 1, Limit, Type]
),
0
end.
10 changes: 4 additions & 6 deletions applications/jonny5/src/j5_hard_limit.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ reconcile_cdr(_, _) -> 'ok'.
%%--------------------------------------------------------------------
-spec calls_at_limit(j5_limits:limits()) -> boolean().
calls_at_limit(Limits) ->
Limit = j5_limits:calls(Limits),
Used = j5_channels:total_calls(j5_limits:account_id(Limits)),
Limit = j5_limits:calls(Limits),
Used = j5_channels:total_calls(j5_limits:account_id(Limits)),
should_deny(Limit, Used).

%%--------------------------------------------------------------------
Expand All @@ -56,8 +56,8 @@ calls_at_limit(Limits) ->
%%--------------------------------------------------------------------
-spec resource_consumption_at_limit(j5_limits:limits()) -> boolean().
resource_consumption_at_limit(Limits) ->
Limit = j5_limits:resource_consuming_calls(Limits),
Used = j5_channels:resource_consuming(j5_limits:account_id(Limits)),
Limit = j5_limits:resource_consuming_calls(Limits),
Used = j5_channels:resource_consuming(j5_limits:account_id(Limits)),
should_deny(Limit, Used).

%%--------------------------------------------------------------------
Expand All @@ -70,5 +70,3 @@ resource_consumption_at_limit(Limits) ->
should_deny(-1, _) -> 'false';
should_deny(0, _) -> 'true';
should_deny(Limit, Used) -> Used > Limit.


2 changes: 1 addition & 1 deletion applications/jonny5/src/j5_limits.erl
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ get_limit_boolean(Key, JObj, Default) ->
end.

-spec get_public_limit_boolean(ne_binary(), wh_json:object(), boolean()) -> boolean().
%% NOTE: all other booleans (inbound_soft_limit, allow_postpay, ect) should
%% NOTE: all other booleans (inbound_soft_limit, allow_postpay, etc) should
%% not be made public via this helper.
get_public_limit_boolean(<<"allow_prepay">> = Key, JObj, Default) ->
case wh_json:get_value(Key, JObj) of
Expand Down
Loading

0 comments on commit 2911e5d

Please sign in to comment.