Monitoring Flights and Sending SMS with Taskmatics Scheduler and Enzo Unified

Software developers need to build solutions quickly so that businesses remain competitive and agile. This blog post shows you how Taskmatics Scheduler and Enzo Unified can help developers build and deploy solutions very quickly by removing two significant pain points: the learning curve of new APIs, and orchestrating Internet services.

Sample Solution

Let’s build a solution that checks incoming flights in Miami, Florida and send a text message using SMS when new flights arrive to one or more phone numbers. To track flight arrivals, we will be using the FlightAware service which provides a REST API to retrieve flight information. To send SMS messages, we will be using Twilio’s service which provides an API as well for sending messages.

To remove the learning from these APIs, we used Enzo Unified, a Backend as a Service (BaaS) platform that enables the consumption of services through native SQL statements. Enzo Unified abstracts communication and simplifies development of a large number of internal systems and Internet services. In this example, Enzo Unified is hosted on the Microsoft Azure platform for scalability and operational efficiency.

To orchestrate and schedule the solution, we used the Taskmatics Scheduler platform. Taskmatics calls into your custom code written in .NET on a schedule that you specify, which is configured to connect to Enzo Unified in the cloud. The call to Enzo Unified is made using ADO.NET by sending native SQL statements to pull information from FlightAware, and send an SMS message through Twilio. At a high level, the solution looks like this:

High Level call sequence between Taskmatics Scheduler and Enzo Unified

High Level call sequence between Taskmatics Scheduler and Enzo Unified

How To Call FlightAware and Twilio with Enzo Unified

Developers can call Enzo Unified using a REST interface, or a native SQL interface. In this example, the developer uses the SQL interface, leveraging ADO.NET. The following code connects to Enzo Unified as a database endpoint using the SqlConnection class, and sends a command to fetch flights from a specific airport code using an SqlCommand object. Fetching FlightAware data is as simple as calling the “Arrived” stored procedure against the “flightaware” database schema.

var results = new List<ArrivedFlightInfo>();

// Connect to Enzo Unified using SqlConnection
using (var connection = new SqlConnection(parameters.EnzoConnectionString))
  // Prepare call to FlightAware's Arrived procedure 
  using (var command = new SqlCommand("flightaware.arrived", connection))
  {
    connection.Open();
    command.CommandType = System.Data.CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("airport", airportCode));
    command.Parameters.Add(new SqlParameter("count", 10));
    command.Parameters.Add(new SqlParameter("type", "airline"));

    // Call FlightAware's Arrived procedure 
    using (var reader = command.ExecuteReader())
      while (reader.Read())
        results.Add(new ArrivedFlightInfo
        {
          Ident = (String)reader["ident"],
          AircraftType = (String)reader["aircrafttype"],
          OriginICAO = (String)reader["origin"],
          OriginName = (String)reader["originName"],
          DestinationName = (String)reader["destinationName"],
          DestinationCity = (String)reader["destinationCity"]
          // ... additional code removed for clarity...
        });
    }

Calling Twilio is just as easy. A simple ADO.NET call to the SendSMS stored procedure in the “Twilio” schema is all that’s needed (the code is simplified to show the relevant part of the call).

// Establish a connection Enzo Unified
using (var connection = new SqlConnection(parameters.EnzoConnectionString))
  using (var command = new SqlCommand("twilio.sendsms", connection))
  {
    connection.Open();
    command.CommandType = System.Data.CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("phones", phoneNumbers));
    command.Parameters.Add(new SqlParameter("message", smsMessage));

    // Call Twilio’s SendSMS method
    command.ExecuteReader();
  }

If you inspect the above code carefully, you will notice that it does not reference the APIs of FlightAware or Twilio. Indeed, calling both FlightAware and Twilio was done using ADO.NET calls against Enzo Unified; because Enzo Unified behaves like a native database server (without the need to install special ODBC drivers), authenticating, making the actual API calls, and interpreting the REST results was entirely abstracted away from the developer, and replaced by an SQL interface, which dramatically increases developer productivity. Database developers can call Enzo Unified directly to test FlightAware and Twilio using SQL Server Management Studio (SSMS). The following picture shows the results of calling Enzo Unified from SSMS to retrieve arrived flights from FlightAware.

Calling the FlightAware service using simple SQL syntax in SQL Server Management Studio

Calling the FlightAware service using simple SQL syntax in SQL Server Management Studio

Sending a SMS text message using Twilio is just as simple using SSMS:

Calling the Twilio service using simple SQL syntax in SQL Server Management Studio

Calling the Twilio service using simple SQL syntax in SQL Server Management Studio

How To Schedule The Call With Taskmatics Scheduler

In order to run and schedule this code, we are using Taskmatics Scheduler, which provides an enterprise grade scheduling and monitoring platform. When a class written in .NET inherits from the Taskmatics.Scheduler.Core.TaskBase class, it becomes automatically available as a custom task inside the Taskmatics Scheduler user interface. This means that a .NET library can easily be scheduled without writing additional code. Furthermore, marking the custom class with the InputParameters attribute provides a simple way to specify input parameters (such as the airport code to monitor, and the phone numbers to call) for your task through the Taskmatics user interface.
The following simplified code shows how a custom task class is created so that it can be hosted inside the Taskmatics Scheduler platform. Calling Context.Logger.Log gives developers the ability to log information directly to Taskmatics Scheduler for troubleshooting purposes.

namespace Taskmatics.EnzoUnified.FlightTracker
{
    // Mark this class so it is visible in the Taskmatics interface
    [InputParameters(typeof(FlightNotificationParameters))]
    public class FlightNotificationTask : TaskBase
    {
        // Override the Execute method called by Taskmatics on a schedule
        protected override void Execute()
        {
	     // Retrieve parameters as specified inside Taskmatics
            var parameters = (FlightNotificationParameters)Context.Parameters;

            // Invoke method that calls FlightAware through Enzo Unified
            var arrivedFlights = GetArrivedFlights(parameters);

            // do more work here… such as identify new arrivals
            var newFlights = FlightCache.FilterNewArrivals(arrivedFlights);

            // Do we have new arrivals since last call?
            if (newFlights.Count > 0)
            {
               // Invoke method that calls Twilio through Enzo Unified
               var results = SendArrivedFlightsViaSMS(newFlights, parameters);

		  // Update cache so these flights won’t be sent through SMS again
		  FlightCache.SaveFlightsToCache(newFlights); 
            }
            else
                Context.Logger.Log("SMS phase skipped due to no new arrivals.");

            Context.Logger.Log("Job execution complete.");
        }
    }
}

Installing the task into the Taskmatics Scheduler platform is very straightforward. Log into the user interface and create a definition for the flight tracker task. This step allows you to import your library into the system to serve as a template for the new scheduled task that we will create next.

Import your custom task as a definition

Import your custom task as a definition

Schedule your custom task to run on the days and times you specify.

Schedule your custom task to run on the days and times you specify.

Once you have created your definition, go to the “Scheduled Tasks” section of the user interface, and create the task by selecting the definition that you just created from the Task dropdown. This is also where you will schedule the time and frequency that the task will run as well as configure the input parameters for the task.

Configure the parameters for the scheduled task.

Configure the parameters for the scheduled task.

Finally, from the Dashboard screen, you can run your task manually and watch the output live, or look at a past execution of the task to see the outcome and logs from that run. In the image below, you can see the execution of the Flight Tracking task where we monitored recent arrivals into the Miami International Airport (KMIA).

Review and analyze previous task executions or watch your tasks live as they run.

Review and analyze previous task executions or watch your tasks live as they run.

Conclusion

This blog post shows how developers can easily build integrated solutions without having to learn complex APIs using simple SQL statements, thanks to Enzo Unified’s BaaS platform. In addition, developers can easily orchestrate and schedule their libraries using the Taskmatics Scheduler platform. Combining the strengths of Enzo Unified and Taskmatics, organizations can reap the following benefits:

  • Rapid application development by removing the learning curve associated with APIs
  • Reduced testing and simple deployment by leveraging already tested services
  • Service orchestration spanning Internet services and on-premises systems
  • Enterprise grade scheduling and monitoring

About Blue Syntax Consulting

Our mission is to make your business successful through the technologies we build, create innovative solutions that are relevant to the technical community, and help your company adopt cloud computing where it makes sense. We are now making APIs irrelevant with Enzo® Unified. For more information about Enzo Unified and how developers can access services easily using SQL statements or a simple REST interface, visit http://www.enzounified.com or contact Blue Syntax Consulting at info@bluesyntaxconsulting.com.

About Taskmatics

Taskmatics was founded by a group of developers looking to improve the productivity of their peers. Their flagship application, Taskmatics Scheduler, aims to boost developer productivity and reduce the effort involved in creating consistent and scalable tasks while providing a centralized user interface to manage all aspects of your task automation. For more information and a free 90-day trial, visit us or email us at info@taskmatics.com.

Dials and Switches – Building Configurable Tasks

As a developer, it’s rare to see an application that doesn’t make use of external configuration settings. Whether it’s to set the connection string to a database or to store custom keys with the credentials to a service being consumed, configuration settings are a ubiquitous tool for developers. It’s not a mystery why this is the case as there are many advantages to using configuration settings when developing. Here are some of the key values that configuration settings can add to an application.

Reconfiguration without Recompilation

Many times an application will need to make use of values that can change after deployment. A prime example of this would be the connection string for data storage. Many times these connection parameters differ based on the environment to which the application is being deployed. Hard coding these values into the program itself introduces the need to recompiling and deploying the code each time any of these values are changed. This leads to poor maintainability of the code base and an inability to easily deploy applications across multiple environments. External configuration allows us to centralize and maintain all of the parameters of an application independent from the build and deployment process.

Reusability of code

Another frequent use for configuration settings can be seen in applications that share common behavior while differing only in the data they work with. For example, if I’m writing an application that zips up a directory and sends the zipped contents to a backup drive, I wouldn’t want to duplicate the application each time that a new folder needed to be backed up. External configuration settings allow for reuse of common logic while providing a way to introduce non-static data elements.

Basic Data Validation

Configuration not only allows you to specify parameters for use within your applications, but they also define a general syntax that allows for rules to be created that control the validity of the values entered for those parameters. The ability to restrict data types, specify string patterns and control a host of other criteria over the values being set increases the integrity of the data and the application itself because developers know what to expect when referencing these parameters in the code.

Configuration Options in Taskmatics Scheduler

There are a couple of ways to specify configuration values in the scheduler. Standard .NET configuration files are supported and are managed in the file system. In addition, the scheduler API allows developers to create their own custom parameters objects that can be used to describe input or output values for their custom scheduler components. Furthermore, the parameters objects are dynamically translated into a custom form in the administration website where the values can be set when creating or modifying scheduler components. The two methodologies can be used in conjunction with one another, so you can use both of them if you so desire.

.NET Configuration files

Tasks for the Taskmatics Scheduler are written in .NET, therefore they include support for .NET configuration files. When developing a custom scheduler component, simply adding an app.config to your project will allow you to access that configuration from your code. Here are some key things to know about using .NET configuration files when you create scheduler components:

  • Using .NET configuration files does not preclude you from being able to use a custom parameters object as the two mechanisms can be used in conjunction. You may want to use .NET configuration to define database connection strings while using a custom parameters object for specifying service address Uri values.
  • In the scheduler system, updating a configuration file requires that you locate the folder where the file is stored and update the file at that location. This can be done from the administration website by updating that file from the built in file management screens. It can also be done from the file system directly, but production deployment folders often have restricted permissions making this strategy less than ideal.

Custom Parameters Object

The scheduler API allows developers to create their own objects that can define the input or output parameters of the components they create. These objects are nothing more than classes that are linked to the components that they are creating. Consider a sample configuration for a task that copies files from a source folder to a destination folder:

public class CopyTaskParameters
{
    public string SourceFolderPath { get; set; }
    public string DestinationFolderPath { get; set; }
}

 

This class gives us a basic parameters object for copying files between two folders, but the custom API allows us to also specify some basic validation criteria of these properties using well known attributes from the DataAnnotations .NET library. Adding that to our example we have something like:

public class CopyTaskParameters
{
    [Required]
    [Display(Name = "Source Copy Path", Description = "The folder that files will be copied from.")]
    public string SourceFolderPath { get; set; }

    [Required]
    [Display(Name = "Destination Copy Path", Description = "The folder that files will be copied to.")]
    [RegularExpression(@"\w{1,100}")]
    public string DestinationFolderPath { get; set; }
}

 

As you can see from the above, it’s fairly trivial to describe the parameters object and even set some basic validation. As a last step, we need to link this object to the task that we’re developing so that the scheduler can associate the task with the configuration object when we are administering the task later on.

[InputParameters(typeof(CopyTaskParameters))]
public class CopyTask : Taskmatics.Scheduler.Core.TaskBase
{
    protected override void Execute()
    {
        var copyParameters = (CopyTaskParameters)Context.Parameters;

        //your task implementation goes here
    }
}

 

In the code above, we’re linking the CopyTaskParameters object to the CopyTask by using the InputParameters attribute from the scheduler API. When scheduler components are linked to custom parameters objects, the administration website will use the custom parameters object to display an entry form for users to configure those parameters directly from the website. It will also provide validation feedback to the user to ensure that the data being entered is what’s expected by the parameters object. Once the task is initiated by the system, it will create an instance of the CopyTaskParameters object and pass it in as part of the Context object that’s accessible from the task. Here’s a shot of what our configuration object will look like when we’re configuring our task from the website:

copy-task-sample-config-ui

Here are some key points to keep in mind when using custom parameter objects in the scheduler system:

  • Like .NET configuration files, custom parameter objects allow you to avoid hardcoding data elements that may change frequently or that don’t warrant a recompile of the code.
  • Custom parameter objects are integrated with the administration website to make managing the configuration for custom tasks easy. It abstracts the need to know the .NET configuration file schema so that non developers can tweak configuration when desired.
  • Currently developers can only use scalar and enumeration properties in a custom parameters object. List and complex object support are to be added in future releases.

Summing It Up

Regardless of the complexity of application you write, using external configuration settings will go a long way towards making your code more versatile and facilitate the maintenance of your application post deployment. Taskmatics Scheduler allows you to use the methods you already know and love, and also introduces a new, simple way to manage external settings that integrates seamlessly with the administration website. For a fully working sample that contains the code used in the article, head over to our GitHub repository, and for more information and more advanced configuration scenarios, check out the online documentation.