Problem/Motivation
Currently gateways are implemented as separate modules with all the code implemented in the foo.module file and callbacks defined in the foo_gateway_info() function. We want to change this approach and implement gateways as D8 Plugins. There are several good reasons to do this:
- There is a lot of boiler-plate code and repetition which would be eliminated by implementing gateways as objects, making it easier to write gateways. DX++
- Gateway module code is only needed when sending sms via that gateway, but currently is loaded at every page load and kept in memory causing memory bloat. As objects, all that code is lazy-loaded only when needed.
- A common interface can be enforced to ensure required methods are implemented.
- More than one gateway can be implemented by a single module - less module overhead.
- One single gateway plugin can be used to implement multiple gateways.
All the above are the reasons for D8 in the first place and right now is the best practice architecturally.
Proposed resolution
- Implement a gateway plugin manager in sms module that uses AnotatedDiscovery to find sms gateway plugins
- Implement a base class for gateway plugins that contains all the basic functionality of sms gateways
- Retain the current hook_gateway_info based gateways for backward compatibility and convert them to gateway objects
Remaining tasks
Patch
Reviews / Testing
Commit
User interface changes
- The SMS Default gateway selection page now has checkboxes for enabling / disabling each gateway. Selecting a disabled gateway as default in the UI automatically enables it. But the default gateway cannot be disabled.
- Configurable gateways have to be created as they don't exist by default. Non-configurable gateways exist by default once the plugin exists.
API changes
- Added a
GatewayManagerInterfaceto represent services that manage sms gateways. - Added a
GatewayManagerclass implementingGatewayManagerInterfaceand the correspondingplugin.manager.sms_gatewayservice. - Added the
SmsGatewayplugin annotation type for annotating gateway plugins. - Added a
GatewayInterfaceto represent SMS Gateways and implemented aGatewayBasebase class. - Moved the log gateway to a
LogGatewayplugin class. - Added a
SmsMessageProviderInterfaceto represent sms messaging providers. - Added a default
SmsMessageProviderInterfaceimplementation calledDefaultSmsProviderand the correspondingsms_provider.defaultservice, which does basically what thesms_send(),sms_incoming(),sms_receipt(), etc. used to do. More complex implementations of SMS messaging including multiple-gateway routing and load-balancing systems can subclass this default implementation. - Added a
DeliveryReportControllerfor receiving and handling delivery reports. - Added a
SmsMessageResultInterfaceto represent the report / result that is returned by sms gateways for sms send requests. A default implementationSmsMessageResultis also added.
| Comment | File | Size | Author |
|---|---|---|---|
| #29 | gateway_plugins-2292319-29.patch | 76.75 KB | almaudoh |
| #29 | interdiff.txt | 6.97 KB | almaudoh |
| #25 | gateway_plugins-2292319-25.patch | 76.57 KB | almaudoh |
| #25 | interdiff.txt | 1.59 KB | almaudoh |
| #20 | interdiff.txt | 6.65 KB | almaudoh |
Comments
Comment #1
almaudoh commentedComment #2
almaudoh commentedFirst go at this. Tests not included. Also included a BC-shim to allow this patch to work with existing gateways.
Comment #3
almaudoh commentedRe-roll
Comment #4
almaudoh commentedComment #6
almaudoh commentedThe first version did not allow multiple instances of the same type of gateway plugin to be instantiated.
This iteration adds that, making it possible to create a generic gateway that only needs to be configured e.g. https://www.drupal.org/project/sms_simplegateway so only one plugin for multiple gateways.
Also introduced the possibility to enable and disable gateways. This is useful for more advanced use-cases where multiple gateways could be used. Selecting a disabled gateway as default in the UI automatically enables it.
Also fixed some of the test fails, cleaned up functions and moved them to the correct classes, renamed classes and services to more appropriate names.
Comment #8
almaudoh commentedFixing the test fails. Corrected hook implementations and some renames.
Comment #9
almaudoh commentedDue to the size of this patch, I have split off the aspect of implementing sms messaging providers as services into a different issue and posted a patch there. Will follow through with that aspect and then continue with this when that issue lands. I have also created a meta issue (now called Plan issue) to help track such refactoring efforts #2509560: [Meta] Revamp SMS Framework in D8 - improve flexibility and scalability
Comment #10
almaudoh commentedComment #11
almaudoh commentedComment #12
almaudoh commented#2509566: Convert sms_send() into a service is in so we can now continue work on this...
Edit: corrected wrong issue link.
Comment #13
almaudoh commentedRe-rolled.
Comment #15
almaudoh commentedRerolled.
Comment #16
almaudoh commentedType-hint
$resultasarrayMight make more sense to name the function argument
$gateway_idand then$gwcan be correctly named$gatewayDelivery reports is strictly not in this scope. Would make the patch easier to review if this is removed to another issue...
Type-hint
$resultasarrayComment #17
almaudoh commentedFixed comments in #16.
#16.2: opened #2542790: Implement API for delivery reports for SMS Gateways
Also opened #2542784: Add unit tests for SMS Gateway and Gateway Manager to add unit tests for the new classes.
With those follow-ups I think this can go in.
Comment #18
almaudoh commented??? Exception should be thrown. And a test should be added for this in the follow-up issue
Comment should be in the body of the function. And logger is the new name now.
Comment #20
almaudoh commented1. Some more clean up.
2. Reverted the array type-hinting, causing problems. Opened #2542866: Clarify the API for message results after sms_send() to take care of that.
3. Implemented default methods in
GatewayBaseComment #22
almaudoh commentedFixed test fails. Made the implementation of HookGateway more robust and seamless with existing plugin architecture.
Comment #24
almaudoh commentedRemove extra space
Comment #25
almaudoh commentedTest base classes should be
abstract.Comment #26
almaudoh commentedComment #29
almaudoh commentedUpdated patch after #2556201: Update 8.x-1.x branch to match new config_object schema
Comment #32
almaudoh commentedCommitted and pushed to 8.x-1.x