The process of modernizing legacy applications into a service-oriented architecture is a long one. For many, the logic that is required for new, modern systems already exists in the form of code that has already been written, fully tested, and used for multiple years in the form of thick-client Windows applications. The process of starting over, defining cloud APIs and re-implementing the logic and data tier can prove to be time-consuming and error-prone.
Thriftly.IO provides a safer alternative route to modernizing existing business logic by offering a service that leverages your existing business logic code and data tier as-is, and exposes it as a reusable cloud-native web service. This allows companies to leverage technology assets they already own, while still modernizing their fleet of applications. This reuse avoids adding technical debt to your organization during the modernization process.
Let’s take a look at how this all works by focusing on legacy C# code as an example.
The Situation: Factorant’s Dilemma
Factorant is a fictional factory equipment manufacturer that has been in business for over 40 years. During this time, the company has undergone many evolutions of technology. They are currently experiencing yet another technology disruption — the adaptation and change associated with moving their equipment to the Internet of Things (IoT).
Factorant has many legacy systems, including a tool to help technicians in the field calculate the estimated Overall Equipment Effectiveness for installed equipment based on data obtained from written equipment logs. This was originally packaged as a ruggedized laptop application in C#/WPF, and the company is starting to move their staff to a mobile application running on their smartphones. The calculations for Overall Equipment Effectiveness will also be needed by the new cloud backend systems to calculate actuals based on the IoT telemetry gathered by their newly connected IoT-enabled equipment. As these calculations are required by multiple clients (namely the mobile app and the backend cloud systems), it makes sense to leverage the code already created in the Windows WPF application and centralize it, exposing this logic as a reusable web service.
In this article, we will focus on extracting the existing logic from the WPF application to expose it as a RESTful web service that can be consumed by both the cloud backend systems and the new mobile application.
First steps - Setting up your account, software, and licensing
To take advantage of Thriftly.IO services, you must first register for an account. The registration process is a painless one and simply requires your email address. You will receive an email asking you to complete the registration process by selecting a password and filling out a short, basic profile form.
Now that your account has been created, you are able to log into the system and view your dashboard.
Click on the "Build Your Application" icon on the dashboard home page, then click the middle download icon to download and install the latest version of Thriftly Developer for Windows. If it is not already installed, this installation will also request that SQL Server Express 2014 LocalDB be installed.
Upon successful installation of the software, it is time to obtain a developer license — A trial license is enough for our purposes. Click on the right-most "Get a Trial License" icon to obtain a trial license, and one will be generated for you.
From the dashboard menu, select Development Licenses — Now you will see the registration code assigned to you. Click on the registration code, and the tile will flip, allowing you then to copy the code to your clipboard.
With the code in the clipboard, open the Thriftly Developer Assistant application from your Windows Start menu. Click the button to Enter Reg Code and paste the contents of your clipboard. Your trial license will now be activated, and you can close the Thriftly Developer Assistant application.
Business Logic Code Overview
The OEE Calculator application has a lot of code that is relevant to the presentation of the UI and the interaction with the user. When it comes to extracting business logic for a Thriftly service, we are only interested in a subset of this code. Let’s look at the business logic code embedded within this specific application.
The business logic class
using Factorant.OEE.WPF.Models;
namespace Factorant.OEE.WPF.BL
{
public class OeeCalculator
{
public OeeCalcModelOut CalculateOee(OeeCalcModelIn inbound)
{
OeeCalcModelOut returnValue = new OeeCalcModelOut();
returnValue.PlannedProductionTime = _calculatePlannedProductionTime(inbound.ShiftLength, inbound.Breaks);
returnValue.RunTime = _calculateRunTime(returnValue.PlannedProductionTime, inbound.StopTime);
returnValue.GoodCount = _calculateGoodCount(inbound.RejectCount, inbound.TotalCount);
returnValue.Availability = _calculateAvailability(returnValue.RunTime, returnValue.PlannedProductionTime);
returnValue.Performance = _calculatePerformance(inbound.IdealCycleTime, inbound.TotalCount, returnValue.RunTime);
returnValue.Quality = _calculateQuality(returnValue.GoodCount, inbound.TotalCount);
returnValue.Oee = _calculateOee(returnValue.Availability, returnValue.Performance, returnValue.Quality);
return returnValue;
}
private decimal _calculatePlannedProductionTime(decimal shiftLength, decimal breaks)
{
return shiftLength - breaks;
}
private decimal _calculateRunTime(decimal plannedProductionTime, decimal stopTime)
{
return plannedProductionTime - stopTime;
}
private decimal _calculateGoodCount(decimal rejectCount, decimal totalCount)
{
return totalCount - rejectCount;
}
private decimal _calculateAvailability(decimal runTime, decimal plannedProductionTime)
{
if (plannedProductionTime == 0)
return 0;
return runTime / plannedProductionTime;
}
private decimal _calculatePerformance(decimal idealCycleTime, decimal totalCount, decimal runTime)
{
if (runTime == 0)
return 0;
return (idealCycleTime * totalCount) / (runTime * 60);
}
private decimal _calculateQuality(decimal goodCount, decimal totalCount)
{
if (totalCount == 0)
return 0;
return goodCount / totalCount;
}
private decimal _calculateOee(decimal availability, decimal performance, decimal quality)
{
return availability * performance * quality;
}
}
}
The inbound model
namespace Factorant.OEE.WPF.Models
{
public struct OeeCalcModelIn
{
public decimal ShiftLength;
public decimal Breaks;
public decimal StopTime;
public decimal IdealCycleTime;
public decimal TotalCount;
public decimal RejectCount;
}
}
The outbound model
namespace Factorant.OEE.WPF.Models
{
public struct OeeCalcModelOut
{
public decimal PlannedProductionTime;
public decimal RunTime;
public decimal GoodCount;
public decimal Availability;
public decimal Performance;
public decimal Quality;
public decimal Oee;
}
}
Introducing Thriftly into the WPF application
The first step in extracting the logic for the service is to introduce the Thriftly server to the source code. Open the App.xaml.cs and introduce the Thriftly Server by overriding the application OnStartup
method as follows:
using System.Windows;
using Thriftly.Server;
namespace Factorant.OEE.WPF
{
public partial class App : Application
{
private ThriftlyServer _server;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
_server = new ThriftlyServer();
_server.AddService(new BL.OeeCalculator(), "OeeCalculatorService");
_server.StartServer();
}
}
}
Next, we will open the class that contains the business logic — In this case: BL\OeeCalculator.cs and adding the using statement ‘Thriftly.Server
’ and adding the ‘PublishedAttribute
’ attribute on the method(s) that you wish to have exposed through the service. That is all the modification we need to do!
Testing the Thriftly service locally
Start the application, and wait for a few moments for the Thriftly Server to start up and display a window like the following:
In this window, you can set the transport, protocol, encoding, and port on how you wish your service to be exposed. For now, let’s just set the protocol to JSON-REST, then click the Start Thriftly button. An Internet browser will open and allow you to add values to a JSON request to send to the service. Make sure you append the Service Name to the URL, then press Send to initiate a request to the service and view the resulting data. You are now free to close this browser window and stop the Thriftly Server (however, keep the application running for the next step!).
Moving the Thriftly Service to the cloud
Making your service available in the cloud is also an easy task. Simply go back to your Thriftly Developer window and check the "Enable Gateway" checkbox. Then select a gateway region nearest to you geographically. Finally, click on the Start Thriftly button once more to have your on-premises logic exposed through a native cloud service!
A browser window is displayed that will show you the endpoint and services that you can interact with.
Copy the location URL for the OeeCalculatorService to your clipboard. Then you can use a tool such as Postman to author a request to this service. Alternatively, you can also click the "Test API" link associated with the service and test from within your browser.
Conclusion
Thriftly.IO allows organizations to leverage existing code and infrastructure assets to define new cloud-based APIs. These APIs are made available via multiple transport options and protocols that you can choose from. Thriftly.IO also implements JWT security when desired, thus providing a well-rounded solution to exposing business logic in the cloud.