101t / jasmin-web-panel

📨 Jasmin Web Panel for Jasmin SMS Gateway
https://youtu.be/z-BFJzWtq1M
81 stars 78 forks source link

Does not allow you to create Failover MT Route #48

Open RyanPrice-King opened 2 years ago

RyanPrice-King commented 2 years ago

DefaultRoute: A route without a filter, this one can only set with the lowest order to be a default/fallback route StaticMTRoute: A basic route with Filters and one Connector RandomRoundrobinMTRoute: A route with Filters and many Connectors, will return a random Connector if its Filters are matching, can be used as a load balancer route FailoverMTRoute: A route with Filters and many Connectors, will return an available (connected) Connector if its Filters are matched

101t commented 2 years ago

Hey @RyanPrice-King What is your suggestion to resolve "Failover MT Route" ?

RyanPrice-King commented 2 years ago
jcli : mtrouter -a
Adding a new MT Route: (ok: save, ko: exit)
> order 30
> type FailoverMTRoute
jasmin.routing.Routes.FailoverMTRoute arguments:
filters, connectors
> filters filter_4
> connectors smppc(smppcc_4);smppc(smppcc_5)
> rate 0.0
> ok
Successfully added MTRoute [FailoverMTRoute] with order:20
jcli : mtrouter -l
#Order Type                 Rate    Connector ID(s)                     Filter(s)
#20    FailoverMTRoute      0 (!)   smppc(smppcc_3), smppc(smppcc_4)    <T>
#20    RandomRoundrobinMTRoute 0 (!)   smppc(smppcc_2), smppc(smppcc_3)    <T>
#10    StaticMTRoute        0 (!)   smppc(smppcc_1)                     <T>, <T>
#0  DefaultRoute            0 (!)   smppc(smppcc_default)
Total MT Routes: 3`
jcli : morouter -a
Adding a new MO Route: (ok: save, ko: exit)
> type FailoverMORoute
jasmin.routing.Routes.FailoverMORoute arguments:
filters, connectors
> filters filter_4
> connectors http(http_4);http(http_5)
> order 30
> ok
Successfully added MORoute [FailoverMORoute] with order:20

main/core/smpp/mtrouter.py

77    def create(self, request):
        """Create MTRouter.
        Required parameters: type, order, smppconnectors, httpconnectors
        More than one connector is allowed only for RandomRoundrobinMTRoute and FailoverMTRoute
        ---
        # YAML
        omit_serializer: true
        parameters:
        - name: type
          description: One of DefaultRoute, StaticMTRoute, RandomRoundrobinMTRoute, FailoverMTRoute

I noticed with this that the code allows for accidental overwrites of an existing route that has the same order number. Up to you, but I would prefer myself to prevent accidental route replacement.

    try:
        self.retrieve(order)
    except Exception:
        pass
    else:
        raise MissingKeyError('MT route already exists')
        rtype = rtype.lower()
        self.telnet.sendline('mtrouter -a')
        self.telnet.expect(r'Adding a new MT Route(.+)\n' + INTERACTIVE_PROMPT)
        ikeys = OrderedDict({'type': rtype})
125     if rtype != 'defaultroute':

To get the try/catch to work you may have to remove ', None' from: 58 next((m for m in routers if m['order'] == order), None)

You can either do this change or not, or even code it to handle the None response. That is up to you.

The FailoverMTRoute is configured exactly the same as the RoundRobinMTroute and also requires at least 2 connectors.

139     if rtype == 'randomroundrobinmtroute':
            if len(connectors) < 2:
                raise MutipleValuesRequiredKeyError(
                    'Round Robin route requires at least two connectors')
            ikeys['connectors'] = ';'.join(connectors)
    elif rtype == 'failovermtroute':
            if len(connectors) < 2:
                raise MutipleValuesRequiredKeyError(
                    'Failover route requires at least two connectors')
            ikeys['connectors'] = ';'.join(connectors)

This might not be a complete copy/paste for you and the morouter.py would require the same kind of changes, but gives you an idea :).

It is not possible to use a FailoverMORoute with a mix of connectors, example: connectors smpps(user_1);http(http_1);http(http_3), so you would only have HTTP MO connectors assigned to the FailoverMORoute and use a filter for SMPP connectors. When an MO is received from one of the SMPP connectors, it validates against the connector filter assigned to the FailoverMORoute and sends down one of the HTTP connectors.

You can do this with the RoundRobinMORoute though, but I do not see a problem with still using filters for the smpp connectors that route to multiple HTTP based on the MO filters.

Then the new options need to be added to frontends I assume: <option>DefaultRoute</option><option>StaticMTRoute</option><option>RandomRoundrobinMTRoute</option><option>FailoverMTRoute</option>

and I think you have to add to models. main/core/models/smpp.py morouter_types = (("DefaultRoute", "DefaultRoute",), ("StaticMORoute", "StaticMORoute",), ("RandomRoundrobinMORoute", "RandomRoundrobinMORoute",), ("FailoverMORoute", "FailoverMORoute",),) mtrouter_types = (("DefaultRoute", "DefaultRoute",), ("StaticMTRoute", "StaticMTRoute",), ("RandomRoundrobinMTRoute", "RandomRoundrobinMTRoute",), ("FailoverMTRoute", "FailoverMTRoute",),)

I have not done a lot of python and especially front end with python, so I am hoping you would be able to take it from here.

101t commented 2 years ago
101t commented 2 years ago

Hi @RyanPrice-King I just have updated source code as you mentioned above in the new branch 2.0.2 for "FailOverRouter supports to MT / MO Router" issue, please check if everything working properly, thanks.

RyanPrice-King commented 2 years ago

OK for some reason with the old master branch and 2.0.2, I cannot create RoundRobinMTRoute or FailoverMTRoute as it says requires 2 connectors error. Even when I drag highlight both connectors.

I have printed the connectors from mtrouter.py and it is only passing the second choice in the list from the frontend. So the connectors being passed is only 1, even though I select more than 1 in the front end.