Introduction
in this article, we will build the Outbound SMS Service. This servicese provide a simple outbound SMS client that allows the application to send text messages. It is structurally similar to the OutboundEmailService created in the previous two articles. The primary differences between the two services exists in the REST controllers and the service class.For this implementation, we will be using Twilio as our SMS service provider. They provide a free trial which gives you an opportunity to exercise the OutboundSMSService without spending any money.
Requirements
Before you get started, you will need the following:- Java
- Maven
- Docker
- Docker-Compose
Building the Outbound SMS Service
Since the OutboundSMSService is so similar to the OutboundEmailService, we will be focusing on just the REST controller, Message Queue Listener, OutboundSMSService interface, and the TwilioOutboundSmsServiceImpl components in this article. If you have not read the previous two articles detailing the OutboundEmailService, we strongly suggest reading them prior to this article.The Source
Maven pom.xml
loading...
The major difference between the OutboundSMSService pom.xml and its OutboundEmailService is the addition of the Twilio dependency, and the removal of the spring-boot-starter-mail dependency
Configuration Files
bootstrap.yml
loading...
application.yml
loading...
As we did in the OutboundEmailService, we configure the message queue name ( cloud.stream.bindings.input.destination=SmsMessages) and the group name ( cloud.stream.bindings.input.group=smsMessagesGroup).
twilio.yml
loading...
Here we include the Twilio authID and accountSID configuration that is used by the TwilioOutboundSmsServiceImpl.
Outbound SMS models
Sms Request
loading...
MMS Request
loading...
Services
We start by defining the OutboundSmsService interface.Outbound Sms Service
loading...
The interface defines two methods, a sendSmsMessage(...) and a sendMmsMessage(...).
Twilio Configuration Properties
We provide a separate configuration file specificially for the Twilio service implementation.loading...
The class is annotated with @ConfigurationProperties to instruct the framework to load it when it loads the application configuration properties. The @PropertySource("classpath:twilio") instructs the framework where to load the configuration properties from.
Twilio Outbound Sms Service Impl
loading...
A class-level annotation ( @Service) is supplied to mark this as an implemention of the OutboundSmsService. We then @Autowire the TwilioConfigurationProperties. Both the sendSmsMessage(...) and the sendMmsMessage(...):
- Call the initTwilio method to set the configuration AccountSID & authID
- Call Twilio's Message.creator static method with appropriate values
- Call the create() method which initiates sending the message.
External API
The service API consists of a REST endpoint and a Message endpoint.REST controller
loading...
The OutboundSMSController provides a REST endpoint that is invoked to send SMS and MMS messages.
Message Queue Listener
loading...
The SMSQueueListener binds to the SmsMessages.smsMessageGroup queue, and inspects incoming messages Type header for routing information. Messages containing the the Type header SMS and MMS messages are routed to the processSmsMessage and processMmsMessage methodmethods respectively.
Metric Collection
The Outbound Email Service collects to metrics:- outbound.sms.plain- Counts the number of email sent without attachments.
- outbound.sms.attachment- Counts the number of email sent with attachments
Docker-Compose
We continue the process of extending our previous Docker-Compose file:loading...
Here we add the outbound-sms-service and override any environment-specific configuration parameters.
Outbound SMS Service in action
We can copy the Docker-Compose file above to your local machine and run it from the command prompt:$ docker-compose -f ./dc-06-outbound-sms.yml up -d
Exercising the Swagger Interface
When all the services have started, navigate to the following url: http://localhost:6020/swagger-ui.htmlClick on the outbound-sms-controller option.
Click on the /sendSMS option.
The /sendSMS method accepts two parameters-
- Accept-Language- this is an optional parameter that we can pass to instruct the service's I18N resolver to internationalize the service's error response. This field will set the request's Accept-Language header value. If no value is set, or the value is not a supported language code, the service will respond with its default values.
- Request- This parameter is the JSON representation of the request model.
Now the interface will display input fields where we can enter our test data. In the request field you will see an editable JSON template, and we can modify the values to suit our needs. The sourceNumber must be the number assigned to your Twilio account. The destinationNumber is the receiver of the text. If you are using a trial Twilio account, you can only send messages to a verified number that must be configured in the Twilio administration interface.
Once we have edited the parameters we can click the Execute button which will call the REST endpoint.
Once the call has completed, the Swagger UI will display the results of the request.
Excercising the Message Listener from the RabbitMQ web admin console
Now that we have demonstrated the REST endpoint, we can turn our attention to the message-driven interface. Of course we have to ask how can we test a message consumer when we haven't built a message producer? As luck would have it, we actually have a way to send a message to our OutboundSmsService. When we deployed the RabbitMQ service container, we configured it to provide access to its web-based administration tool. In addition to monitoring the message broker, the administration tool provides a mechanism for us to enqueue messages. We start by opening a browser window and navigating to http://localhost:15672/.We authenticate with the credentials we set in the application.yml or we pass in through our Docker-Compose file. The default username/password credentials for the reference implementation are think/microservices
Once you have entered your credentials you should see the RabbitMQ administration tool's Overview tab.
This tab provides the landing page for the administration tool. We won't stay here for long though. Click on the Queues tab.
Unfortunately, since we don't have a message producer yet, we will have to create message queue manually.
Fortunately, RabbitMQ makes this fairly trivial. We simply complete the Add a new queue form, entering SmsMessages.smsMessageGroup as the queue name, set Durability to Durable, and set Auto Delete to No, then press the Add Queue button.
We now have a message queue that we can publish messages to, and our OutboundEmailService can consume from. Click on the EmailMessages.emailMessageGroup to view the queue details:
From this page we can monitor the queue's activity, and more importantly, publish a message. Select the Publish message option to display the input form:
To publish a message to the queue:
- Set the Delivery mode to 1 - Non-persistent.
- Set the Header field to type and its value to SMS
- Then set the Payload with the JSON message in the format:
{ "sourceNumber": "xxxxxxxxxx", "destinationNumber": "yyyyyyyyyy", "message": "this is an outbound message" }
- Now press the Publish Message several times in quick succession to enqueue several email messages.
We can see the message publishing activity reflected in the Message rates chart above. To verify that the message was actually sent, you can either check the Twilio usage logs, or simply verify the message was received on the device associated with the destinationNumber.
Metrics and Monitoring
The Outbound SMS Service will also contain the following service-level metrics to:- outbound.sms.send.total
- outbound.mms.send.total
To visualize this data we will import the OutboundSMSDashboard.json file from the ThinkMicroservices Github Dashboards repository. The dashboard should appear as:
Resources
- OutboundSmsService Github repository.
- OutboundSmsService Docker hub image.
- ThinkMicroservice OutboundSmsService Dashboard.
Twitter
Facebook
Reddit
LinkedIn
Email