Rewriting HotOrNot

372 views
Skip to first unread message

Sergey Korobkov

unread,
Nov 14, 2016, 9:42:11 AM11/14/16
to 2600hz-dev
Hi.

There was several threads about rewriting HotOrNot, but i didn't see any changes in it, so I decided to rewrite HotOrNot by myself.
What I planing to change:
  • Move rate CSV export/import into "tasks" application (via cb_tasks)
  • Allow reseller to have own ratedeck (for its descendant accounts, not for itself), this ratedeck will be in separate DBs
  • Rate search will use account tree to search reseller with enabled ratedeck (will going up till master-account ratedeck)
  • Configurable options for searching rates (set list of options in system_config):
    • Direction
    • Resource flags
    • Outbound flags (account, user, device)
    • Service plan
    • ???
Maybe rates should have binds with stepswitch application? Or maybe integrated into stepswitch, so we will have one application wich will reply on route_req and rate_req using same data from same DB.
Any thoughts?

Darren Schreiber

unread,
Nov 14, 2016, 9:54:33 AM11/14/16
to 2600h...@googlegroups.com

Hi Sergey,

                It’d be awesome to improve hotornot! Thanks for the offer.

 

                I think your suggestions are good. The issues we’ve had before is that, when people post about this, they want to “allow reseller to have their own ratedeck”. I think this is a bad thing because it doesn’t scale. The rate lookups are views, and those become expensive. Right now we heavily cache the rates but if every reseller or, worse, customer had their own view lookups the system would get really slow and the lookups would be expensive. Also, we had intended to change this to track actual cost, so the rate would be based on which carrier ended up being selected + the rate.

 

                If there’s a way to factor that into the work you do so that we come up with an intelligent way of distributing the workload for rate lookup, then I would think this would be a pretty amazing addition to the core.

 

                Also, the only thing I don’t think makes sense that you’ve listed below is configurable options based on “service plan”. I would think flags in stepswitch should cover that already, but I could be wrong.

 

                Otherwise, I think this sounds amazing and would be happy to participate in working the details out.

 

-          Darren

--
You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kirill Sysoev

unread,
Nov 14, 2016, 10:33:52 AM11/14/16
to 2600h...@googlegroups.com
Hi

Thanks for raising up this questions again! :)
It is good to know, that this problem isn't forgotten somewhere in deep dead end.

As for me (and this is just my 2 cents), Sergey's list contains only one problem makes me sad.
And yes, Darren, it is "allow reseller to have their own ratedeck". :)

But let's look at it from another angle - "allow reseller to EDIT their own ratedeck"

Since my PR https://github.com/2600hz/kazoo/pull/2709,
which was classified by Luis as a sort of a temporary hack (https://2600hz.atlassian.net/browse/KAZOO-5124),
we can store rates for different resources and therefore for different resellers in one database.

Since we can apply rate discounts based on number/direction classification
and these could be configured for each account separately,
we already have quasi-multi-ratedecking.

So, we can see from this angle, that only "allow reseller to EDIT their own ratedeck" is lacking.
And still, we can live with one DB where different resellers could co-exist.
(Amount of rates per reseller could probably be limited ...)

Regards,
Kirill

PS Just my 2 cents. Don't kick me hard :))

Darren Schreiber

unread,
Nov 14, 2016, 10:37:12 AM11/14/16
to 2600h...@googlegroups.com

Hi Kirill,

                As always, the work you do is appreciated.

 

                The reason it was not accepted, though, was it still does not address the issue I brought up. The ratedeck table, with your strategy, will just get bigger and bigger, thus slower and slower. The goal of this entire project was to try and cater to high-volume environments and, frankly, we have enough work to do to find all the edge cases on that without introducing new ones! So that is why we were hesitant to accept it.

 

                We had wanted the ratedecks to be in separate DBs ultimately so that:

1) A reseller might be able to re-use a ratedeck across multiple accounts and have it hit the same DB for the lookups

2) A reseller could then have their own DB on a different BigCouch/Couch cluster (including their accounts and rate decks and voicemails and what-not) so that any load they do cause doesn’t impact other clients

 

By putting them all in one DB, without answering the scalability question, it has the potential to cripple the system. Since I suspect this feature will actually be popular, that causes a problem – then everyone will discount the capabilities of the entire system (this seems to be a tendency when people find bugs) as not scalable.

 

So we have to find a way to make it scale before we accept it. And we haven’t quite figured out that way yet but I think a combination of what you’ve done plus the above notes / and/or Sergey’s suggestions will work.

Kirill Sysoev

unread,
Nov 14, 2016, 11:20:17 AM11/14/16
to 2600h...@googlegroups.com
Hi Darren,

thanks for detailed answer.


> 2) A reseller could then have their own DB on a different BigCouch/Couch cluster (including their accounts and rate decks and voicemails and what-not) so that any load they do cause doesn’t impact other clients


This option, which feels to be an extension of kazoo_data, looks especially exciting!
This way we even could be able to choose whether we want to separate resellers' DBs or not.
Absolutely perfect!

Regards,
Kirill

Sergey Korobkov

unread,
Nov 14, 2016, 11:29:07 AM11/14/16
to 2600hz-dev
So we should add new type of DB in data-mgr "ratedeck"?

понедельник, 14 ноября 2016 г., 18:20:17 UTC+2 пользователь kirill.sysoev написал:

Darren Schreiber

unread,
Nov 14, 2016, 11:30:04 AM11/14/16
to 2600h...@googlegroups.com

I don’t want to say “we should” as if this is well designed J

 

I think I was tossing out ideas. I would want James or Karl to validate them probably.

 

From: <2600h...@googlegroups.com> on behalf of Sergey Korobkov <skoro...@gmail.com>


Reply-To: "2600h...@googlegroups.com" <2600h...@googlegroups.com>
Date: Monday, November 14, 2016 at 8:26 AM
To: 2600hz-dev <2600h...@googlegroups.com>

Subject: Re: Rewriting HotOrNot

James Aimonetti

unread,
Nov 14, 2016, 4:20:41 PM11/14/16
to 2600h...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

So I had this in my backlog from a long time ago and this ML post got me
to try it out:

https://github.com/2600hz/kazoo/pull/2798

Basically, we load the ratedeck database into a trie in memory and do
lookups there instead of using the couch view.

Tradeoffs:

1. Lookups are two orders of magnitude faster (~16 milliseconds vs ~0.1
milliseconds using the trie)
2. Memory consumption is higher (9 MB for the 78,009 rates used in my
test) but it won't change once loaded.

The idea being, this could be extended to start a server per ratedeck
database, which could bind itself to AMQP to listen for rate requests
using a ratedeck id. Then we could figure out how to start one ratedeck
process within a zone (or X spread over running hotornot instances (so
if we run 3 instances and X is 2, ratedeck A is running on nodes X and
Y, ratedeck B on Y and Z, etc).

Anyway, this future work is half-baked in my mind at the moment, but I
wanted to get some numbers on what a trie-based solution could look
like.

Thoughts?

James

Darren Schreiber writes:

> I don’t want to say “we should” as if this is well designed ☺
> * Move rate CSV export/import into "tasks" application (via cb_tasks)
> * Allow reseller to have own ratedeck (for its descendant accounts, not for itself), this ratedeck will be in separate DBs
> * Rate search will use account tree to search reseller with enabled ratedeck (will going up till master-account ratedeck)
> * Configurable options for searching rates (set list of options in system_config):
>
> * Direction
> * Resource flags
> * Outbound flags (account, user, device)
> * Service plan
> * ???
> Maybe rates should have binds with stepswitch application? Or maybe integrated into stepswitch, so we will have one application wich will reply on route_req and rate_req using same data from same DB.
> Any thoughts?
> --
> You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<javascript:>.
> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<javascript:>.
> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<javascript:>.
> For more options, visit https://groups.google.com/d/optout.
> --
> You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<javascript:>.
> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<mailto:2600hz-dev+...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEcBAEBCAAGBQJYKiqnAAoJENTKa+JPXCVgErwH/1mFUl2SCvnq2c0AaneW3uv/
gi3eQr5sf8zCAEK+wXaj8Yr20cGJ7ny76kJ+17uGfy98kxCmlvzh7KBGUPNixAQq
pDnSwRoh/Aa2RoEDR9d1L58QVfr/CulObcUUNBASpr8MfzVI8LguWfpkKo9ViJIQ
7vMVPF3KXg8V84WrtAyfasL3qzGrZT79ohnqnL8VW51W7sEBvrzuPP6gLq13UlO0
iXMUVZGpnTKPOEyKKzOUgeQ2sQFqVBlIehpPfuleY7nc4czQt/q9fvM6fqNAd5IX
dujt4VeAxF8Oetr1CpufsElsyeO5BNMg8Emycwno4+2eu7ivT/6yMDAHRWnILZY=
=sC6/
-----END PGP SIGNATURE-----

James Aimonetti

unread,
Nov 14, 2016, 4:28:35 PM11/14/16
to 2600h...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

As I think about it a bit more, sharding the trie should be
straightforward too.

We could estimate the size of the trie for the ratedeck in question
(number of prefixes * ~115 bytes) and apply a heuristic to figure out
how many shards (max being 9, 1 per prefix). Then start workers with
their prefix range (if 2 shards, 1-4 and 5-9, say). Rate lookups are
then routed to the appropriate worker.
iQEcBAEBCAAGBQJYKix/AAoJENTKa+JPXCVgl3UH/3EoBobAIr75lq3QLPNB07Fg
I/+c9Uwje5bGM4C/obG8lIJRr49Yeo9o7IV7wfU6FzNs2NLnNz1lqi5AFn+ms2cI
CG5TckaT7YpCV+TrirSohVMmtjWR4TWwVHEiIHo7CeWzAAWSjRxtLvy82WDDYJVt
j1wFI+g4MlHziiKuCjcc/7dvQ6FICnKTQziniWQBa/bBRTYSsXTBBqZsGdFMukgw
aLLb+HIOve39bTqmG0k3g9JfQFXffDFJRG53VN2g6INhWcbu1AUGL3OjWf3kMLIh
n2sSrj/fTKJ4GS2LAv4wLXRwgbs3TOYAwSdJ1yiw3RBn3Lw1PB5Vyfo2ULsyu6E=
=JaZw
-----END PGP SIGNATURE-----

Kirill Sysoev

unread,
Nov 14, 2016, 5:14:32 PM11/14/16
to 2600h...@googlegroups.com
Hi James!

Do not stop please :)

Regards,

Sergey Korobkov

unread,
Nov 15, 2016, 7:33:29 AM11/15/16
to 2600hz-dev, dschr...@2600hz.com
> Also, the only thing I don’t think makes sense that you’ve listed below is configurable options based on “service plan”. I would think flags in stepswitch should cover that already, but I could be wrong

The reason why I had added this option - several rate plans, one of them can be applied to customer.
For now we use our own rate engine (which uses ets tables to store and search rates). Rate plan selects by certain key in account's doc.
But I understand that this scheme is not good. So I think using service plans for this more proper way.
All that has anything to do with the money should be tied to service plans. Is not it so?


понедельник, 14 ноября 2016 г., 16:54:33 UTC+2 пользователь Darren Schreiber написал:

Sergey Korobkov

unread,
Nov 16, 2016, 9:57:04 AM11/16/16
to 2600hz-dev, ja...@2600hz.com
What is your vision of ratedeck's future?

Will it move to in-memory tables, and rates DB go away?
Or rates DB will stay and coexist with in-memory tables?

How about some weird idea: rates stored in ratedeck DB, but index stored in trie table in HotOrNot process?
Key is prefix (and options?), value - document ID (to minimise memory consumption). Fetching document from couchdb by doc_id is almost constant time (~ 3-4ms).
Generaly speaking we move view from couchdb to our process.

понедельник, 14 ноября 2016 г., 23:20:41 UTC+2 пользователь James Aimonetti написал:

Kirill Sysoev

unread,
Nov 16, 2016, 10:13:18 AM11/16/16
to 2600h...@googlegroups.com
Looks like it already works like that - looks for docs Ids in memory, but reads options from couch:

https://github.com/2600hz/kazoo/blob/74f72b842bfa4e261727213d201dae11a5c8753a/applications/hotornot/src/hon_trie.erl#L46-L65
--
You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com.

Sergey Korobkov

unread,
Nov 16, 2016, 10:27:39 AM11/16/16
to 2600hz-dev
Oh...
First version hon_trie didn't do this.

среда, 16 ноября 2016 г., 17:13:18 UTC+2 пользователь kirill.sysoev написал:

Sergey Korobkov

unread,
Nov 16, 2016, 10:41:49 AM11/16/16
to 2600hz-dev
I forgot about feature that I realy want - start/stop date for rates.

понедельник, 14 ноября 2016 г., 16:42:11 UTC+2 пользователь Sergey Korobkov написал:

Kirill Sysoev

unread,
Nov 16, 2016, 10:41:49 AM11/16/16
to 2600h...@googlegroups.com

James, just don't stop!!! :)))

James Aimonetti

unread,
Nov 16, 2016, 1:06:36 PM11/16/16
to 2600h...@googlegroups.com, dschr...@2600hz.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

I like the idea of a service plan including the ratedeck to use.

One thing to consider is what to do when two or more service plans are
assigned to an account, any number of which have ratedecks
associated. Which one to use? How to determine it?
- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEcBAEBCAAGBQJYLKApAAoJENTKa+JPXCVgxd8H/jnOsA8/OPb+t4CwQcWqF+kv
3nt5PskizywhXB2U7nQp6Bj5fHS+FktEMI2COv4iIBBGvTlgP7cV9J/MRnMJVJar
Xj9z99j81GL8LjT3eHnDZyDSnEevc7UVxGhPmgN2Kqn0rltJy43fC84/JKhJnZxz
YbCad0becaM6xx4euiVvgo47Crti3S9j+Q1BLxuBZDftVj6haZLL576TTiOxkOtO
m6kq2oo3k95v6nEXtMx5TB6KjnKvWylkScx0wT1LlRUH7ZQzpx82VotfgwNjRT1/
iJAqDby57c8++SE19ZBqwB27pnaebEJq9WJkLCrgyR9fuKS6uLMpVf1DlAA1KO8=
=1Kp1
-----END PGP SIGNATURE-----

James Aimonetti

unread,
Nov 16, 2016, 1:07:09 PM11/16/16
to 2600h...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Haha, I don't plan to stop; I will be able to more fully engage Friday
or next week though.
iQEcBAEBCAAGBQJYLKBKAAoJENTKa+JPXCVg38kH+wVolJXPNn374/23IIzM5Qu1
fHJjnmxkH5HG6UOHwAB2bSC5ZrX5NCVC+gIGbIseFCL3hPTauxCtoJtwHfAxweB+
HsMmKKJ3iO3GLmCafjGmg8nyak61AMK7+2Uj5uL2WHBKvqYVxV2JdgYpefmA89es
QN/CtXf8e5siaSQ4Ivb8JYMlEyVvmpYkhk3YC0KpGX+7vK90iPzGrjYjdfxHla0K
TxP4b9sSAbI+eZfPzGRJmQhZ6xSXhlx8eSo+bpyVv6CUf2qj63p5+IwqqThX5Brn
NTU+mnhQ2TWgzpcemJx5uZs7ZPqpIQINrLdWo9S1gPh3XeInx6h7qjVrS0ESxuI=
=DJiF
-----END PGP SIGNATURE-----

Sergey Korobkov

unread,
Nov 17, 2016, 7:26:37 AM11/17/16
to 2600hz-dev, dschr...@2600hz.com, ja...@2600hz.com
Yes, I though about it too.
How about create new service item? Lets call it "flag" item.
This service item always count 1.
{
  "pvt_type": "service_plan",
  "plan": {
    "flags": {
      "rate": {
        "name": "rate_1",
        "rate": 10,
        "activation_charge": 5
      },
      "route": {
        "name": "route_2",
        "rate": 15,
        "activation_charge": 10
      }
    }
  }
}
This service plan adds 2 flags, for rating - "rate_1", for riuting - "route_2".
This itmes can be overriden by other service plans, like they do now.

When this service plan applied to customer on reconcilation it will add this "flag" items to its quantities with count equal 1.

среда, 16 ноября 2016 г., 20:06:36 UTC+2 пользователь James Aimonetti написал:

Sergey Korobkov

unread,
Nov 29, 2016, 6:43:34 PM11/29/16
to 2600hz-dev
https://github.com/dinkor/kazoo/tree/pimp_my_rate

What have done:
  • Added module "kt_rates" for "tasks" application. Category "rates", actions "import", "export" and "delete". Only superadmin can use this task.
    Available fields in CSV file:
    • prefix - destination search prefix (mandatory for "import" and "delete" actions)
    • cost - per minute cost (mandatory for "import" action)
    • ratedeck - name of ratedeck (rate plan, rate class, tarif name, etc.) which assigned to account (via services)
    • account - reseller account, which descendants will be allowed to use this rate. Value for this field gets from Account-ID when creating task, value from CSV file ignored.
    • iso - ISO code for country of rate
    • description - description of rate
    • name - name of rate (will be showed in CDR doc), if not set generated from direction, iso and prefix fields
    • surcharge - surcharge for call
    • increment - billing "steps" for call
    • minimum - minimum billing "time" for call
    • internal_surcharge
    • internal_cost
    • direction - if not set then rate will match for both "inbound" and "outbound" calls
    • nocharge_time - will billing call only if its duration greater then this time (seconds)
    • weight - if not set calculated from prefix length and rate cost (the same way as cb_rates do)
  • Configurable list of filters for rates, when matching them to rate request. 
  • Available filters:
    • direction - should we take care about direction of call
    • route_options - matching flags from device/user/account/resource
    • routes - check regexp rules in "routes" field from rate document (kt_rates generate it automaticaly from "prefix" on import)
    • ratedeck - get ratedeck name from account service plans and compare it with "ratedeck" field in rates
    • reseller - get reseller ID for account and compare it with "account" field in rates
  • Default filter list [<<"direction">>, <<"route_options">>, <<"routes">>]. The same behaviour like old HotOrNot.
  • If enabled "trie", then it will be rebuld on ratedeck DB update (when updating via kt_rates)
  • Manual "trie" rebuild via "hotornot_maintenance:trie_rebuild/0"
  • Sort rates by "weight" or by "cost" (set "sort_by_weight": false in hotornot config)
  • configurable defaults for rate responce:(in hotornot config)
    • default_minimum - 60
    • default_increment - 60
    • default_nocharge_time - 0
    • default_surcharge - 0.0
    • default_cost - 0.0
    • default_internal_cost - 0.0
  • Ratedeck name assigned to account by service plan. Create service plan with item like this:
    {
      "pvt_type": "service_plan",
      "name": "ratedeck 1 service plan",
      "plan": {
        "ratedeck": {
          "ratedeck_id_1": {
            "name": "Ratedeck name 1"
          }
        }
      }
    }
    And add this service plan to account. After reconcilation account willl have ratedeck with name "ratedeck_id_1", which can be used for match rates with this name in "ratedeck" field.
    If you try to add second service plan with "ratedeck" item. on reconcilation system alert will be generated (and error message in logs) about this situation. Ratedeck name for account will stay unchanged, until you remove one of conflictiong service plans.

There is still a lot of work.
Need tests.
Need comments (especially from Kazoo team).
PR will be created little further.

Darren Schreiber

unread,
Nov 29, 2016, 7:51:35 PM11/29/16
to 2600h...@googlegroups.com

OMG Sergey! You are a rockstar!!!

 

Nice module name

 

We are about to release a new doc site, can we add this there and maybe accept this module to community-scripts for testing?

 

From: <2600h...@googlegroups.com> on behalf of Sergey Korobkov <skoro...@gmail.com>
Reply-To: "2600h...@googlegroups.com" <2600h...@googlegroups.com>
Date: Tuesday, November 29, 2016 at 2:04 PM
To: 2600hz-dev <2600h...@googlegroups.com>
Subject: Re: Rewriting HotOrNot

 

--

You received this message because you are subscribed to the Google Groups "2600hz-dev" group.

To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com.

James Aimonetti

unread,
Nov 30, 2016, 2:45:23 AM11/30/16
to 2600h...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

I second this! I can't wait to dig into the branch and play with it.

Thanks Sergey!

Darren Schreiber writes:

> OMG Sergey! You are a rockstar!!!
>
> Nice module name
>
> We are about to release a new doc site, can we add this there and maybe accept this module to community-scripts for testing?
>
> From: <2600h...@googlegroups.com> on behalf of Sergey Korobkov <skoro...@gmail.com>
> Reply-To: "2600h...@googlegroups.com" <2600h...@googlegroups.com>
> Date: Tuesday, November 29, 2016 at 2:04 PM
> To: 2600hz-dev <2600h...@googlegroups.com>
> Subject: Re: Rewriting HotOrNot
>
> https://github.com/dinkor/kazoo/tree/pimp_my_rate
>
> What have done:
>
> * Added module "kt_rates" for "tasks" application. Category "rates", actions "import", "export" and "delete". Only superadmin can use this task.
> Available fields in CSV file:
>
> * prefix - destination search prefix (mandatory for "import" and "delete" actions)
> * cost - per minute cost (mandatory for "import" action)
> * ratedeck - name of ratedeck (rate plan, rate class, tarif name, etc.) which assigned to account (via services)
> * account - reseller account, which descendants will be allowed to use this rate. Value for this field gets from Account-ID when creating task, value from CSV file ignored.
> * iso - ISO code for country of rate
> * description - description of rate
> * name - name of rate (will be showed in CDR doc), if not set generated from direction, iso and prefix fields
> * surcharge - surcharge for call
> * increment - billing "steps" for call
> * minimum - minimum billing "time" for call
> * internal_surcharge
> * internal_cost
> * direction - if not set then rate will match for both "inbound" and "outbound" calls
> * nocharge_time - will billing call only if its duration greater then this time (seconds)
> * weight - if not set calculated from prefix length and rate cost (the same way as cb_rates do)
>
> * Configurable list of filters for rates, when matching them to rate request.
> * Available filters:
>
> * direction - should we take care about direction of call
> * route_options - matching flags from device/user/account/resource
> * routes - check regexp rules in "routes" field from rate document (kt_rates generate it automaticaly from "prefix" on import)
> * ratedeck - get ratedeck name from account service plans and compare it with "ratedeck" field in rates
> * reseller - get reseller ID for account and compare it with "account" field in rates
>
> * Default filter list [<<"direction">>, <<"route_options">>, <<"routes">>]. The same behaviour like old HotOrNot.
> * If enabled "trie", then it will be rebuld on ratedeck DB update (when updating via kt_rates)
> * Manual "trie" rebuild via "hotornot_maintenance:trie_rebuild/0"
> * Sort rates by "weight" or by "cost" (set "sort_by_weight": false in hotornot config)
> * configurable defaults for rate responce:(in hotornot config)
>
> * default_minimum - 60
> * default_increment - 60
> * default_nocharge_time - 0
> * default_surcharge - 0.0
> * default_cost - 0.0
> * default_internal_cost - 0.0
>
> * Ratedeck name assigned to account by service plan. Create service plan with item like this:
> {
> "pvt_type": "service_plan",
> "name": "ratedeck 1 service plan",
> "plan": {
> "ratedeck": {
> "ratedeck_id_1": {
> "name": "Ratedeck name 1"
> }
> }
> }
> }
> And add this service plan to account. After reconcilation account willl have ratedeck with name "ratedeck_id_1", which can be used for match rates with this name in "ratedeck" field.
> If you try to add second service plan with "ratedeck" item. on reconcilation system alert will be generated (and error message in logs) about this situation. Ratedeck name for account will stay unchanged, until you remove one of conflictiong service plans.
> There is still a lot of work.
> Need tests.
> Need comments (especially from Kazoo team).
> PR will be created little further.
> --
> You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<mailto:2600hz-dev+...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEcBAEBCAAGBQJYPoOQAAoJENTKa+JPXCVgTaIH/1sOVhc73rMOU+w6e3MpBf6W
HjiHNlbEACSp7+G4MRO63kbyT4ilE3Hk3AW/0oJHqkpi4dmf6l+GkcHbuiLPHovt
pswVAKTr7jO1p+Eq6tsY4PVj16NZ8f6Yw6SdgacKYy+9ISeFPno7CF3G/CfSi2hK
RWjP1h+Tb6xJxqGKDPSmj0fTQS3NAhdtlkRSdXY+bi9p4z2w2ULBsghuikMgeqcj
0YAKg/mtwNInCjinaU2Fyrtm7yIUHw6EkROZw6xGpBTlA3/PLSHk40//xag5DmU2
U4XUz23Wa8ncTFjiskw3yOcxBeM+rJYQSBkd4TNV/eliy6VPnFEtskAJM9IzexA=
=z237
-----END PGP SIGNATURE-----

Sergey Korobkov

unread,
Nov 30, 2016, 6:45:58 AM11/30/16
to 2600hz-dev, ja...@2600hz.com
James, since you are here, i have some qeustions about rates.
"weight", "routes", "internal_cost" and "internal_surcharge" - is these fields used by anyone in work? Maybe it is time to say "bye" them?
  • "weight" in our setup always equal 1 (because we dont use dollars as currency). And this field used only when two rates have the same prefix lenght, maybe we should use "cost" for sorting instead? Or maybe use some other method for chosing rate if we have several after filtering.
  • "routes" - I beleve using prefix match is more logical and clear for telecom
  • "internal_*" - I didn't found where they used (except internal_cost for weight calculating)

среда, 30 ноября 2016 г., 9:45:23 UTC+2 пользователь James Aimonetti написал:
> To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com<mailto:2600hz-dev+unsubscribe@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com

Sergey Korobkov

unread,
Dec 5, 2016, 4:57:15 PM12/5/16
to 2600hz-dev

Kirill Sysoev

unread,
Dec 6, 2016, 7:28:40 AM12/6/16
to 2600h...@googlegroups.com
Hi Sergey,

is there any thoughts to make resellers manage their rates by themselves over crossbar?

Regards,

On 06.12.2016 00:56, Sergey Korobkov wrote:
--
You received this message because you are subscribed to the Google Groups "2600hz-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to 2600hz-dev+...@googlegroups.com.

Sergey Korobkov

unread,
Dec 6, 2016, 9:58:31 AM12/6/16
to 2600hz-dev
For now you can upload rates via tasks (cb_tasks ot tasks_maintenance).
Set account_id field in rates to reseller_id and add to system_config/hotornot/filter_list "reseller" filter.

Currently only superadmin can load rates into "ratedeck" DB. I had functionality to upload rates by reseller, but I removed it because i wasn't shure in its security.

вторник, 6 декабря 2016 г., 14:28:40 UTC+2 пользователь kirill.sysoev написал:

James Aimonetti

unread,
Dec 6, 2016, 12:58:13 PM12/6/16
to 2600h...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

I am reviewing this today - will provide comments on the PR soon!
>> email to 2600hz-dev+...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhG/DIACgkQ1Mpr4k9c
JWDOZgf/fd3JJlCtWHO4+DL5d4q/EFsF/ORebF39dYVYE6LCbJBbk+Fh+EHgLxFZ
/LrwJmWxK2+ZKyyzrD9TGiRkVwu4fn1XQomiBG8eVpjRjhQKoQFNRb9nRV/p9UN9
cOf1YewnGw1RK11S3Gah0x4kWGxPA8G+49lnm8d29DvFfJEUsczQxFytCYgX8+1J
Ngzt3HEszs5JIAahRekGqaCHiVdIElna/7HGdsvGCO+8n6rs4Nm1kNnnQI6rk8ky
kqY+p8rLlM/CMIvKcTSt1jlsevBoWBh8rj9nwyUrroDj8F3PfgA84/Os4g3Ejstt
YdrL0m3yJq6G+9cMl887X5T03KFHyg==
=Uchp
-----END PGP SIGNATURE-----

James Aimonetti

unread,
Dec 6, 2016, 4:37:33 PM12/6/16
to 2600h...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi Sergey,

I made some comments on your PR. I'm also making some changes as I play
with the branch and am pushing them here:

https://github.com/2600hz/kazoo/tree/dinkor-pimp-my-rate
>> email to 2600hz-dev+...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhHL5oACgkQ1Mpr4k9c
JWBGeAf+NavXfbT4RSW+xAdb3+CAwZqGAdcL+QxQQ65K7tczSmbdYkmycKb2fCAK
ttz2343jCuJbx0sJzGGe3XcUoPSNijSuhX0puGtBLY+kgtT2beVUgVwc5BcuvI4z
37RMOt0DW2clGwhZgfIbXGnmM08PGGUEfj11Wnzc3cUocplPrS3cD6RkNXypbR32
IQkTd4oxkVrZwASZAtH0w6Y/KIuie3iSUl/ZoyRSQR9wS9HjcFH0hq7WnplzGAGi
e2CNOeflzc4297+r4aIAx6CxNd72NfBPFqMzIVhFVWgZ1sp9Nz0Wry4sXDnWBwaK
BNurl7Guh498iapevoU6iUgt9/SdOw==
=NDLC
-----END PGP SIGNATURE-----

Xen

unread,
Dec 16, 2016, 12:16:29 PM12/16/16
to 2600hz-dev, ja...@2600hz.com
Hi guys! This is a really awesome and needed feature. What is the status of this? 

James Aimonetti

unread,
Dec 16, 2016, 12:27:18 PM12/16/16
to 2600hz-dev
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Still reviewing it. I know some requests were made that were addressed -
I just need to have a second pass on it.

I also need to go over the supplied docs (yay!) and make sure I can
properly setup a new system *and* upgrade an existing system to use the
new code.
>> sip:...@2600hz.com <javascript:>
>> tel:415.886.7905
>> irc:mc_ @ freenode
>> -----BEGIN PGP SIGNATURE-----
>>
>> iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhHL5oACgkQ1Mpr4k9c
>> JWBGeAf+NavXfbT4RSW+xAdb3+CAwZqGAdcL+QxQQ65K7tczSmbdYkmycKb2fCAK
>> ttz2343jCuJbx0sJzGGe3XcUoPSNijSuhX0puGtBLY+kgtT2beVUgVwc5BcuvI4z
>> 37RMOt0DW2clGwhZgfIbXGnmM08PGGUEfj11Wnzc3cUocplPrS3cD6RkNXypbR32
>> IQkTd4oxkVrZwASZAtH0w6Y/KIuie3iSUl/ZoyRSQR9wS9HjcFH0hq7WnplzGAGi
>> e2CNOeflzc4297+r4aIAx6CxNd72NfBPFqMzIVhFVWgZ1sp9Nz0Wry4sXDnWBwaK
>> BNurl7Guh498iapevoU6iUgt9/SdOw==
>> =NDLC
>> -----END PGP SIGNATURE-----
>>


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhUI/QACgkQ1Mpr4k9c
JWBUJAf/Xc+m2D+q3GJXbcHolqqItHcOTdrmZNs/yVgLuRzqmi67laweWCt3CAAT
Du1WJC9fd6R0JRhJAYXswQH0YDBRkQZmEoPTHfoUNaDu6kn3F7v4Xlkn0k2a3Xdr
VIyFUGBw5E0lZu3AGbe1tbDURVXBa5S5eS9dc7aM3ROGhrRSKdaBVb/Py/elmEX3
rDpOL45rW9Z9pEu5vxklSKslxtyDOSCULgQijs1xC2mk5uFK8nE/UenmrCpR9gad
NZmCKazz9jv9g2Ai2mnIfJEmE10xlBMKk0HuLdMrSBgO8o1lH6jtVfSuwQjBkmhS
pXjMvmx3+aoS5zKcIunSSRyA5hwV8g==
=s8yZ
-----END PGP SIGNATURE-----

Xen

unread,
Dec 16, 2016, 1:26:47 PM12/16/16
to 2600hz-dev, ja...@2600hz.com
Thanks for the quick answer James! Will this work on 3.22 or only in 4.0? 

James Aimonetti

unread,
Dec 16, 2016, 1:29:31 PM12/16/16
to 2600hz-dev
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

This will probably be 4.1 at the earliest since 4.0 is tagged and only
bug fixes should be back-ported.
>> iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhUI/QACgkQ1Mpr4k9c
>> JWBUJAf/Xc+m2D+q3GJXbcHolqqItHcOTdrmZNs/yVgLuRzqmi67laweWCt3CAAT
>> Du1WJC9fd6R0JRhJAYXswQH0YDBRkQZmEoPTHfoUNaDu6kn3F7v4Xlkn0k2a3Xdr
>> VIyFUGBw5E0lZu3AGbe1tbDURVXBa5S5eS9dc7aM3ROGhrRSKdaBVb/Py/elmEX3
>> rDpOL45rW9Z9pEu5vxklSKslxtyDOSCULgQijs1xC2mk5uFK8nE/UenmrCpR9gad
>> NZmCKazz9jv9g2Ai2mnIfJEmE10xlBMKk0HuLdMrSBgO8o1lH6jtVfSuwQjBkmhS
>> pXjMvmx3+aoS5zKcIunSSRyA5hwV8g==
>> =s8yZ
>> -----END PGP SIGNATURE-----
>>


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhUMokACgkQ1Mpr4k9c
JWA7DAf9GCi1d1ScjapRVcb+q4w1C1Cpf6raPiFRY+8D2peLQoaZ3lGNottxA8DC
fGW5kp5ZeLJNI2kVFidIwVKOtNBN7wnfouZoYzNF/1Nmxnn1s45OgTX4Q9gQC0uR
vAY/MVPuil777v2ZPOZzlGxCZdQUN0e0a0lwXNjzPv/6cPUZtWTwLZoYQnyQF1Of
S1f6tnbqsdGa5AR32j+eUJUt2UzM7mtDmgcMNFj+uJVGz0C62BcgFuQQjJhg37xz
9LqqjixDeHKbvxbJMZZKsTdSV8jCzxTYCTX5S2BNmttchPYisc2enuRTlk28jDwQ
OtAENN9azF286tmF6B3WDixeOwJkZw==
=G7Dj
-----END PGP SIGNATURE-----

kirill.sysoev

unread,
Dec 18, 2016, 6:57:32 AM12/18/16
to 2600hz-dev
Hi 

Watching this feature gradually maturing, still have fear that the question if resellers can manage their rates by themselves over crossbar will be forgotten and left somewhere in the dead end for a long time. 

So I would suggest to return functionality to upload rates by reseller back, but make it configurable with the DB key in order admins can play with it if they know what they are doing and provide further patches.
Having this, we can proceed elaborating safe way not leaving this question for the next centuries :)

Disclaimer:  Absence of this feature makes me sick :))

Regards,
Kirill

вторник, 6 декабря 2016 г., 17:58:31 UTC+3 пользователь Sergey Korobkov написал:

Sergey Korobkov

unread,
Dec 19, 2016, 9:18:46 AM12/19/16
to 2600hz-dev
I have added this feature.

воскресенье, 18 декабря 2016 г., 13:57:32 UTC+2 пользователь kirill.sysoev написал:

Kirill Sysoev

unread,
Dec 19, 2016, 9:43:47 AM12/19/16
to 2600h...@googlegroups.com
Hi Sergey,

Thanks!

Checked is_allowed/1 and can't find an option to switch this feature on/off  on super_admin level.

Since it is even more 'experimental' than PimpMyRate itself, I believe it should be switched off by default somewhere in system_config -> hotornot

Thoughts?

Regards,
Kirill

Sergey Korobkov

unread,
Dec 19, 2016, 10:25:36 AM12/19/16
to 2600hz-dev
https://github.com/dinkor/kazoo/blob/pimp_my_rate/applications/tasks/src/modules/kt_rates.erl#L282
On import/delete `account_id` will always get value from task account, not from CSV.

понедельник, 19 декабря 2016 г., 16:43:47 UTC+2 пользователь kirill.sysoev написал:

Marcin Muzylo

unread,
Jan 17, 2017, 8:19:09 AM1/17/17
to 2600hz-dev, ja...@2600hz.com
Hi James , do we know when KZ 4.1 will be released ? it will include pimp_my_rate also ?

James Aimonetti

unread,
Jan 17, 2017, 4:33:15 PM1/17/17
to Marcin Muzylo, 2600hz-dev
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

I hope so! I'm currently on paternity leave so haven't been able to
spend much time with the PR since before Christmas. Back next week and
planning on picking the work back up to integrate all the latest commits
and finish up working through it.

Fingers crossed
>> iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlhUMokACgkQ1Mpr4k9c
>> JWA7DAf9GCi1d1ScjapRVcb+q4w1C1Cpf6raPiFRY+8D2peLQoaZ3lGNottxA8DC
>> fGW5kp5ZeLJNI2kVFidIwVKOtNBN7wnfouZoYzNF/1Nmxnn1s45OgTX4Q9gQC0uR
>> vAY/MVPuil777v2ZPOZzlGxCZdQUN0e0a0lwXNjzPv/6cPUZtWTwLZoYQnyQF1Of
>> S1f6tnbqsdGa5AR32j+eUJUt2UzM7mtDmgcMNFj+uJVGz0C62BcgFuQQjJhg37xz
>> 9LqqjixDeHKbvxbJMZZKsTdSV8jCzxTYCTX5S2BNmttchPYisc2enuRTlk28jDwQ
>> OtAENN9azF286tmF6B3WDixeOwJkZw==
>> =G7Dj
>> -----END PGP SIGNATURE-----
>>


- --
James Aimonetti

Lead Systems Architect
"If Dialyzer don't care, I don't care"
2600HzPDX | http://2600hz.com
sip:ja...@2600hz.com
tel:415.886.7905
irc:mc_ @ freenode
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEvSh+xZ5hP1H8lVIU1Mpr4k9cJWAFAlh+jZEACgkQ1Mpr4k9c
JWCDtAf/Q0velCjLu5XFXTFk4t4unaem3LeivR4kWtSyg+LqMix51BPJWrPOp4QR
08My/bRykN3S4Sk5DZXnb8ql1V6mKNnbQapTvOO2yUFyUymK0iE4791x5/jtnrVb
S3hZyrc+XgbdotuFosxWjOSyqZe2RfdLMy+eONiFywo57kaJLZ7Za588ClDJgNt/
0GQhZlUjOWeRBTu15KMKRH/kgARx3EPyD03sIMYkYq3C1147o/R7oG3Lf8LGdRPw
r4tO4urXw2KZYhlX2GSyEOc7R46tGsKIWVzonhU8MmMNo+S5PkUXxPEQcBosoHBJ
218qUlibch+HbVsfkL2nttzsqbQfgg==
=S8yp
-----END PGP SIGNATURE-----

Marcin Muzylo

unread,
Jan 30, 2017, 8:56:57 AM1/30/17
to 2600hz-dev, bi...@ipvoice.pl, ja...@2600hz.com
iam trying to test branch dinkor-pimp-my-rate, but no luck so far ,got service plan with ratedeck assigned to account but  cant upload rates via api:

curl -v -X PUT \
-H "X-Auth-Header: {AUTH_TOKEN}" \
-H "Content-type: text/csv" \
--data-binary @rates.csv \
'http://{SERVER}:8000/v2/tasks?category=rates&action=import'

trying to put csv content:
prefix, rate_cost, ratedeck_name
1, 0.99, "ratedeck_id_1"

but got:

12:56:48.338 error kazoo_bindings.715 unable to find function clause for kt_numbers:help/3
12:56:48.338 error kazoo_bindings.715 unable to find function clause for kt_resource_selectors:help/3
12:56:48.338 error kazoo_bindings.715 unable to find function clause for kt_services:help/3
12:56:48.338 debug kz_amqp_channel.159 published to targeted(amqp://guest:gu...@127.0.0.1:5672) exchange (routing key kazoo...@marcin.myhost.com-<0.834.0>-5a175b11) via <0.2098.0>
12:56:48.340 debug kz_amqp_worker.586 published request with msg id c1d47ae41a38c60f for <0.17266.0>
12:56:48.340 debug kz_amqp_worker.745 response for msg id c1d47ae41a38c60f took 60 micro to return
12:56:48.340 debug kz_tasks.137 task rates import matched api {"description":"Bulk-import rates","doc":"Creates rates from file","expected_content":"text/csv","mandatory":["prefix","rate_cost"],"optional":["ratedeck_name","account_id","iso_country_code","description","rate_name","rate_surcharge","rate_increment","rate_minimum","direction","pvt_rate_cost","pvt_rate_surcharge","rate_nocharge_time","weight","rate_version"]}
12:56:48.340 debug cb_tasks.315 new rates task import cannot be created: {[{<<"missing_mandatory_fields">>,[<<"rate_cost">>]}]}
12:56:48.340 debug api_util.1316 halting execution here with 400

Sergey Korobkov

unread,
Jan 30, 2017, 9:00:39 AM1/30/17
to 2600hz-dev, bi...@ipvoice.pl, ja...@2600hz.com
I don't sure, but try remove spaces in header row...
prefix, rate_cost, ratedeck_name  -->  prefix,rate_cost,ratedeck_name


понедельник, 30 января 2017 г., 15:56:57 UTC+2 пользователь Marcin Muzylo написал:
iam trying to test branch dinkor-pimp-my-rate, but no luck so far ,got service plan with ratedeck assigned to account but  cant upload rates via api:

curl -v -X PUT \
-H "X-Auth-Header: {AUTH_TOKEN}" \
-H "Content-type: text/csv" \
--data-binary @rates.csv \
'http://{SERVER}:8000/v2/tasks?category=rates&action=import'

trying to put csv content:
prefix, rate_cost, ratedeck_name
1, 0.99, "ratedeck_id_1"

but got:

12:56:48.338 error kazoo_bindings.715 unable to find function clause for kt_numbers:help/3
12:56:48.338 error kazoo_bindings.715 unable to find function clause for kt_resource_selectors:help/3
12:56:48.338 error kazoo_bindings.715 unable to find function clause for kt_services:help/3
12:56:48.338 debug kz_amqp_channel.159 published to targeted(amqp://guest:guest@127.0.0.1:5672) exchange (routing key kazoo...@marcin.myhost.com-<0.834.0>-5a175b11) via <0.2098.0>

IPvoice Biuro

unread,
Jan 30, 2017, 9:48:46 AM1/30/17
to Sergey Korobkov, 2600hz-dev, ja...@2600hz.com
yes, whitespaces , works now,  thank you Sergey

W dniu 30.01.2017 o 15:00, Sergey Korobkov pisze:
-- Pozdrawiam / Greetings Marcin Mużyło www.ipvoice.pl tel. +48 858710855 mob. +48 606394048
Reply all
Reply to author
Forward
0 new messages