Using the Built-in SMTP Delivery ProtocolIn this section, we modify the music store application to support the built-in SMTP delivery protocol. Using this protocol allows the application to deliver notifications via email. Although the code in this section is specific to the music store application, the general techniques shown can be used to add SMTP support to any application. Before continuing, it's important to take stock of where we are in the development process. We completed the prototype that showed the application's core logic and then added a subscription management interface, a real event provider, and a real content formatter. There is still work to do before the music store application is ready to be deployed in a production environment, but adding support for a real delivery protocol finally makes it seem less like a prototype and more like real application. Creating an SMTP Delivery ChannelTo use the SMTP delivery protocol, we need to declare a new delivery channel to represent an SMTP delivery endpoint. Listing 10.4 shows the delivery channel declaration in the ICF. Listing 10.4. Declaration of an SMTP Delivery Channel
The declaration appears in a new <DeliveryChannel> element within the existing <DeliveryChannels> element. Note that the new delivery channel does not replace the old file delivery channel. It's usually a good idea to leave the file delivery channel in place because it provides an easy mechanism for debugging distribution problems, should you need to later on. The <DeliveryChannel> declaration specifies a name, SMTPChannel, by which the channel can be identified. As you may recall from looking at the script used to add subscriber devices, this is the channel name used in the creation of the Email subscriber device records. The <ProtocolName> element specifies the name of the delivery protocol that the channel uses: SMTP. The <Arguments> element specifies the delivery channel arguments that the SQL-NS engine passes to the delivery protocol at runtime. Each delivery protocol expects a different set of arguments; the ones shown in Listing 10.4 are specific to the SMTP delivery protocol. The first argument, SmtpServer, specifies the name of the SMTP server to which the protocol should send notifications. Omitting this argument (or providing a blank value as Listing 10.4 does) causes the delivery protocol to use the local SMTP service. Caution Do not specify the actual local machine name in the SmtpServer argument because doing so causes the SMTP protocol to behave in a way that requires the SMTP Service to be running. As is explained later, in our testing, we leave the SMTP Service in the stopped state to prevent our test emails from being relayed off the box. Supplying a blank value for SmtpServer, or omitting the argument entirely, causes the SMTP protocol to use the local SMTP Service without requiring it to be running. Note Although using the local SMTP service is useful for testing the application while it is still in development, it is not a recommended practice in deployment. In a production environment, the local SMTP service usually acts as a relay to a remote SMTP server that does the delivery. Queuing to the local server typically has a negative performance impact, so it's recommended that you specify the name of the remote SMTP server in the channel arguments and let the protocol send mail to it directly. The second delivery channel argument specifies the character encoding to use for the email messages. Table 10.1 shows the legal values for this argument, although not all these encodings are supported on every system. The example shown in Listing 10.4 uses UTF-8 encoding, but in general, you need to choose a value based on the content of your notifications.
Declaring Support for the SMTP Delivery Protocol in the Notification ClassTo use the SMTP protocol to deliver NewSong notifications, we must declare support for it in the NewSong notification class. Listing 10.5 shows this declaration. Listing 10.5. Declaration of SMTP Protocol Support in the NewSong Notification Class
Beneath the existing <Protocol> declaration for the File delivery protocol, there is a new <Protocol> declaration for SMTP. The declaration specifies the protocol name and then defines a set of protocol fields. The protocol fields shown in Listing 10.5 are the ones required by the SMTP delivery protocol. Other delivery protocols require different protocol fields, based on the data they need to deliver notifications. Each protocol field consists of a name and a SQL expression that the distributor evaluates to compute the field value when it reads notification data from the notifications table. When the distributor calls the delivery protocol to deliver a notification, it passes the formatted notification message, along with the values of the protocol fields. Protocol field expressions may be constants, function calls, or expressions over the notification fields. The expressions may also reference the following additional fields:
The declaration in Listing 10.5 defines the following SMTP protocol fields: Subject, From, To, Priority, and BodyFormat. The Subject value is used to populate the subject field of the resulting email and is specified as a constant string. Like computed fields (explained in the section "Adding Computed Fields," p. 318, in Chapter 9), the SQL expressions that define protocol field values must be written so that they could appear in the SELECT clause of a SQL query. You can use constant strings, but they must be surrounded with single quotes (recall that SQL uses single, not double, quotes for literal strings). Because the single quote character is a reserved character in XML, we have to use the ' escape sequence (entity reference) in its place. The SQL expression for the Subject field is given as N'Music Store Song Alert', which is really N'Music Store Song Alert' when the escape sequences are replaced. The N character at the start of the string specifies that it is a Unicode string. When the distributor evaluates the expression for the Subject field, the resulting value will be the string Music Store Song Alert. Caution A common mistake when declaring protocol field expressions is to specify string constants without quotes. This leads to a compile error because unquoted string constants cannot be used in a SQL query. The From and To fields provide values for the sender and recipient addresses on the email message. The From field is defined with a constant string expression, much like the Subject field. Again, the ' escape sequence is used in place of the single quote character. The expression for the To field is given as DeviceAddress. This means that the value of this field will be taken from the DeviceAddress property of the subscriber device record for the notification. The T-SQL script that created the subscriber device records in the music store instance specified email addresses for the DeviceAddress property on email devices. In general, the DeviceAddress property on a subscriber device can be any string that the delivery protocol can interpret. The Priority and BodyFormat protocol fields in Listing 10.5 are both constant strings. The valid values for Priority may be different on the particular email server you are using, but on Microsoft Exchange Server, Low, Normal, and High are valid values. The BodyFormat field indicates whether the notification body (produced by the content formatter) contains text or HTML. The valid values for this field are text and html. Testing SMTP DeliveryThe code in Listings 10.4 and 10.5 is already in the ICF and ADF files you compiled when you set up the instance in the "Re-creating the SQL-NS Instance" section (p. 362) earlier in this chapter. Assuming that you completed the steps in that section, all you need to do to test SMTP support is submit some events that match the email subscriptions. (Make sure that you have also completed the instructions in the "Adding Subscriber Devices for New Delivery Channels" section, p. 365, before proceeding.) Before running the test, we will stop the SMTP service. As a result, when the SMTP delivery protocol delivers the notifications, they will end up in the local SMTP queue, but they will not actually be sent out. We can verify that the application is working by looking at the messages in the SMTP queue. You should always have the SMTP service stopped when running tests on notification applications that use the SMTP delivery protocol because it prevents the test notifications from being delivered off your machine and actually reaching users. Note If other services or applications on your development machine use the local SMTP service, those applications cannot send email while the service is stopped. The "Restoring Your System" section (p. 389) at the end of this chapter describes how to restart the SMTP service when you're finished testing. Use the following instructions to stop the SMTP service, submit the events, and observe the email notifications:
Figure 10.5 shows an email message generated by the music store application. The messages on your system should look similar. Notice that the body of the email is the text generated by our custom content formatter (one of the messages should be formatted in French). Figure 10.5. A notification email generated by the music store application.The email notifications generated are real, and if the SMTP service were running, it would pick them up from the Pickup directory and route them to their recipients. As it currently stands, you have a working notification application that can send email! |