Leonardo - ACE: Airline Customer Experience

Continuous CX Improvement Powered by RHPAM

****Please note that the section at the bottom of this page describes the updates to our submission

Inspiration

In terms of financial performance, the airline industry is perhaps more volatile than any other. Simple cost drivers like the price of aviation fuel can boost or destroy profitability. The growth of budget airlines has heaped pressure on full-service carriers, and competition is as tough is it has ever been. Retaining customers, particularly those who fly regularly, is a key imperative. Every part of the customer journey, from considering booking a flight, to checking in, and from the flight itself to collecting baggage, are all critical touch points that will affect whether the passenger is more or less likely to flight with that airline again.

Frankly most of us don’t like to fly. At its best it is boring, and it's often stressful. One of the worst things an airline can do is leave a passenger in the dark, or be seen as uncaring during those frustrating moments, such as a flight delay, or, worse, cancellation.

Airlines are getting better at sharing information with us. We might receive an SMS, or a push notification informing us of a gate change if we have installed their mobile app on our smartphones. But often this functionality is built inside the airline’s monolithic core business application, which is often millions of lines of COBOL. The problem with a monolith is that any changes require us to regression test the entire application. You can build or change a monolith using Agile methods, but that doesn’t mean you can deploy incrementally. DevOps principles work best with code that is independently deployable, like microservices.

A combination of Agile methods, DevOps, and microservices means that traditional waterfall approaches can be replaced with nimbler, quicker deployments. That is the chief problem airlines face with respect to customer experience: from the time they conceive of a customer experience improvement to the time it is deployed can be as long as nine months. They also report that the time taken to design and develop the change is only about 20% of the lifecycle with testing and deployment making up the other 80%.

An airline able to rapidly and flexibly make customer experience improvements gains a potential competitive advantage over rivals that take months to make similar changes. Red Hat Process Automation Manager on OpenShift creates that opportunity.

What it does

Our application is an RHPAM process-as-microservice developed for "ACE Airlines", our fictional client. It communicates personalised, event-driven (gate change, delay, etc.) messages to passengers in the language of their choice, using their preferred communications mechanism (SMS, push notification, email). A combination of usiness rules determine how we personalise the messages, which range from informational (in response to events, such as a delay, or a gate change, etc.) to marketing offers. The benefit of rules like these is in some cases twofold - it affords opportunity for revenue generation (e.g. discounted offer to upgrade to business class) while doing so in a way that makes the customer feel as if he or she is valued by the airline (such as a free upgrade to business for a platinum frequent flyer). Currently airlines have siloed systems for messaging passengers - one for marketing, one for operations. Our solution allows airlines to combine both in a single, open source solution.

Code share partners can use the same system to send offers via a monestised API. This means that ACE Airlines can treat its code share partners as customers also. Ideally these offers would themselves enhance the customer experience. For example, if an ACE Airlines frequent flyer is joining a code share partner's connecting flight in San Francisco, an offer letting that passenger know they will be charged extra if they don't book luggage on-line and instead purchase it at the check-in counter.

We also added a mock departure board, so that events can be sent not just directly to the passengers, but also to other ACE Airline departments or related parties (of which Departure Boards are one). While airlines have this functionality today it is embedded within their core COBOL mainframe applications. Adding a new event or a new event "subscriber" is a non-trivial matter. Moving this functionality to a rule-driven process would see them be able to make such changes in days, not months.

Note that, with the exception of the mock departure board, the application is "headless", i.e. there is no UI, because the process-as-microservice utilises strainght-through-processing. To demonstrate the software you must send a request to the RHPAM kie-server API using either the Insomnia or cURL requests we have provided in our Bitbucket project (https://bitbucket.org/account/user/leonardo-consulting/projects/RHHACE) which has been open-sourced to the public.

How we built it

We have created a RHPAM process that we call a "process-as-microservice", a straight-through-processing microservice using BPMN to orchestrate the logic. It is instantiated via a RESTful API call that comes via 3scale. The JSON payload contains a passenger manifest. The process contains a multi-instance process that runs a separate instance for each booked frequent flyer member, enabling us to personalise the message, communications mechanism, and the language used. For example, one passenger might receive an SMS in French, and another might receive an email in English, and a third might receive a push notification in German. Business rules are used to generate the message based on an event. If the passenger's preferred method of communication is SMS we can include an image as an MMS, such as a food voucher, or a new boarding pass. If, for example, there is a delay of more than two hours, we can send a message to Silver frequent flyers: "We apologise that flight flightNumber will be delayed for n hours and have sent you a food voucher to use at the food court." and include an MMS containing a barcode for the food court voucher." Or, in German: "Da sich Ihr Flug verspätet hat, bietet GlobalAirlineCo Ihnen gerne diesen $ 20-Gutschein für Lebensmittel an, den Sie in einem der Geschäfte im Food Court einlösen können".

Another business rule says that if the date of departure is tomorrow and there is a platinum frequent flyer booked in economy, and there are five or more empty seats in business, then send the platinum frequent flyers a message offering a free upgrade to business. If, however, there no platinum frequent flyers booked in economy, and there are five or more empty seats in business, we send Gold frequent flyers booked in economy a message offering a 50% discount to upgrade to business.

The open source jBPM Work Item Handler for Google Translate is used to translate the outbound message into the passenger's preferred language. We know what the passenger's preferred language is because we have created a mock node.js microservice called getFFdetails which is called by a REST task. We also use REST tasks to call a Telstra SMS API to firstly get a token and then to send an SMS (and possibly MMS where relevant).

We also created our own custom Work Item Handler which we have submitted to https://github.com/kiegroup/jbpm-work-items via a pull request. This Work Item Handler reads config from a properties file. Things like URLs for REST task calls that are different across different environments can be stored in a properties file and loaded at run-time. This means that the RHPAM deployments across dev, test, prod, etc. are identical because the Work item Handler loads the environment-specific properties (the "inventory") dynamically at run-time.

We also reasoned that if one of the primary benefits of our solution is that changes can be made and deployed within days instead of months then we should add a Jenkins pipeline to further speed up deployment. This required adding a Nexus Maven repository.

Challenges we ran into

There were some serialisation issues when POSTing the JSON payload to the kie-server API that we resolved with a minor change to the POJO.

We suspected that the Telstra SMS API does not correctly support foreign language characters with accents, meaning "einlösen können" is received as "einl~sen k~nnen" as the umlauts are unrecognised. We then realised that the RHPAM REST task now supports a parameter called "ContentTypeCharset". Once we set this to UTF-8 "einlösen können" was received correctly in the SMS body.

We were also less than 100% familiar with how the Mult-Instance Sub Processes work (in particular how the MI Collection is passed to each sub-process instance), but a blog post by Maciej Swiderski (https://planet.jboss.org/post/multiinstance_characteristic_example_reward_process) swiftly got us underway.

Accomplishments that we're proud of

As I am a Solution Architect who has never been a developer I was proud of a few problems I solved, not least of which was the aforementioned problem vis-à-vis special characters not being correctly rendered in the SMS body, and which was fixed by adding "ContentTypeCharset=UTF-8" to the REST task that called the SMS API. This was particularly so because I was proud of the idea to use the Google Translate work item handler to translate messages into the passengers' preferred language if it wasn't English.

I was also pleased that we put this together so quickly. Less than ten person days were used for the RHPAM development, even though there were a few things we were relatively unfamiliar with, such as the Multi-Instance sub-process, the Telstra SMS API (especially the UTF-8 issue), and the Google Translate Work Item Handler. It was gratifying that, with the exception of the DRL rules, the majority of the RHPAM component of the solution was put together by a non-developer, whose knowledge of Java doesn't extend much past "System.out.println". This is important because the overwhelming majority of our clients DON'T want to have to use Java developers in process automation projects. There is a small amount of Java in Entry/Exit Actions and in Script tasks but it is a small amount of code relative to the overall solution. If we were building this for a Production-ready solution we would do somethings differently - some of the Script Tasks for instance we would replace.

I was very proud of the Leonardo team member who created our first ever custom Work Item Handler, as this is not something we had attempted previously. Now I envisage us cereating these regularly so that they can be reused across multiple client projects and minimise the need for custom Java code on a case-by-case basis.

But most of all I was pleased with the overall concept, because I personally have heard airline industry IT executives bemoaning how difficult it is to meet the business's demand for changes when the monolithic and mission critical mainframe application requires a vast amount of regression testing before changes can be deployed to production. Moving this functionality out of the monolith and into RHPAM, and using DRL and/or DMN to personalise interactions with passengers would allow changes or additions to be made in days, instead of months. Our solution supports ongoing continuous improvement to CX rather than a one-off improvement. It also recognises that CX is a superset of UX. Using RHPAM to develop what is in essence a microservice instead of doing it in node.js or Spring Boot isn't unique but is still innovative, still independently deployable, and, importantly for an airline, can scale out horizontally on OCP, with more pods deployed with rising demand.

What I learned

As mentioned previously, I am not (and have never been) a developer, so I had to teach myself how to modify a simple node.js "listener" application that another team member had created, adding an NPM module called "json-query" so that when the Multi-instance Sub-process calls the "getFFdetails" node.js microservice / API, it returns the details only for the frequent flyer whose frequent flyer is passed in as an input parameter:

var resultPayload = jsonQuery('frequentFlyers[**][frequentFlyerNo=' + body + ']', {
    data: freqFlyerData
}).value;

I also learnt that I to encode an image as Base64 to allow it to form part of the JSON payload sent to the SMS/MMS API.

I also learned a lot about UTF-8 and how its use is essential if we are dealing with non-English character sets.

What's next for ACE: Airline Customer Experience

What we would like to add in future are more alerts (similar to the updated departure board). The way this would work is that business rules would identify which subscribers are relevant for a given event, then what message is relevant to the subscriber, and inform each subscriber (catering, maintenance, departure boards, ground staff, etc.) via another multi-instance process via the appropriate channel.

If we get to the last 15 we would like to implement a small mobile app (Flutter or Cordova) that receives a Push Notification from the process, which would also require a node.js or Spring Boot microservice to communicate with both APN and GCM.

If we were to find an airline client interested in taking this to the "real world" (and we have at least three airlines in mind!) we would consider implementing a Work item Handler for the execution of PMML, and we would definitely implement the functionality for sending Push Notifications and emails, both of which in our submission are mocked with a node.js listener that simply writes the payload to a file. We would also add Prometheus monitoring for both RHPAM & APIcast.

GitHub Repositories (Public)

RHH-ACE RHPAM Code Repo
RHH-ACE Departure Board Demo Code Repo
RHH-ACE getFFdetails Code Repo
RHH-ACE node-connect Code Repo
Forked jBPM Work Items Code Repo
RHH-ACC-receive-sms-reply

GitHub Issues Raised

Apicast Re-write Rules based on HTTP Verb
Deployment Issue with RHPAM 7.4.x on OpenShift

GitHub Pull Request

jBPM Work Item Handler Submitted

Leonardo Team Members

Andre McGuire - process, rules, and microservices development
Daniel Weatherhead - video & animation production
Mizanur Rahman - mock Departures Board development
Phil Ogilvie - solution design and process and microservices development
Ricardo Hernandez - 3scale API & Jenkins pipeline

Updates to our Second Round Submission

We allow Codeshare Partners of ACE Airlines to submit offers to frequent flyers via the paid plan of our 3scale API. These are sent out in the passenger's preferred language, via their preferred comms mechanism (as per our previous submission only SMS messages are sent; emails and push notifications are stubbed). The test case we have used is a message that is sent only to those passengers that have not purchased check-in luggage for the connecting flight on XYZ Airlines, warning them that purchasing luggage at the counter will be more expensive than pre-purchasing it online. They are invited to reply with "Yes" / "Oui" / "Ja" (or any equivalent of "Yes" as per their preferred language if they would like to receive pricing for pre-purchasing luggage. If they do so, the Telstra SMS API sends a payload to our newly created node.js API endpoint.

The original process we developed now includes a reusable sub-process that is instantiated for every instance of the multi-instance sub-process in the process in our original submission, receiving the SMS messageID, the passenger details, and the passenger's frequent flyer information. The top-level process does not wait for the reusable sub-process to finish before completing. The new sub-processes wait for the node.js micro-service to receive a signal where the signal reference is the messageID. Thus if we send an SMS to Jim and the response from the SMS API says the messageID is "8EDFFE35A305EA61959701000500BA73" then when node.js sends a signal with signalRef of "8EDFFE35A305EA61959701000500BA73" we know that it is Jim who has replied to our outbound SMS, because Jim's process instance is waiting for that exact signalRef (which was passed in an as input from the calling parent process) and the rest of the process logic is then "activated" by the catching intermediate event signal. We then knowe what Jim's preferred language is, and, having looked up checked-in baggage pricing that is specific to the specific airline (in this case XYZ Airlines) we send the relevant pricing information to Jim by return SMS in Jim's preferred language. This way we help Jim avoid "sticker shock" by getting stung for much higher luggage pricing - a potentially uplifting customer experience for Jim if we help him save money and stay a happy customer of both ACE and XYC. Note that the reusable sub-process that keeps running after its parent process has terminated will itself keep running until the offer (e.g. purchase check-in baggage online) will self-terminate via a timer at the appropriate time (e.g. once the original ACE Airlines flight that connects to the connecting XYC Airlines flight has departed).

We also increased the event-driven messaging to ACE Airlines departments, staff, or related parties. One such innovation is, in response to an event like a gate change, we identify passengers who may require special assistance, such as an unaccompanied minor, or a person with a disability, and let ground staff know that these people might need help getting from the old gate to the new gate, especially if a person with a disability has mobility issues.

Built With

Share this project:

Updates

posted an update

Updates to our Second Round Submission

We allow Codeshare Partners of ACE Airlines to submit offers to frequent flyers via the paid plan of our 3scale API. These are sent out in the passenger's preferred language, via their preferred comms mechanism (as per our previous submission only SMS messages are sent; emails and push notifications are stubbed). The test case we have used is a message that is sent only to those passengers that have not purchased check-in luggage for the connecting flight on XYZ Airlines, warning them that purchasing luggage at the counter will be more expensive than pre-purchasing it online. They are invited to reply with "Yes" / "Oui" / "Ja" (or any equivalent of "Yes" as per their preferred language if they would like to receive pricing for pre-purchasing luggage. If they do so, the Telstra SMS API sends a payload to our newly created node.js API endpoint.

The original process we developed now includes a reusable sub-process that is instantiated for every instance of the multi-instance sub-process in the process in our original submission, receiving the SMS messageID, the passenger details, and the passenger's frequent flyer information. The top-level process does not wait for the reusable sub-process to finish before completing. The new sub-processes wait for the node.js micro-service to receive a signal where the signal reference is the messageID. Thus if we send an SMS to Jim and the response from the SMS API says the messageID is "8EDFFE35A305EA61959701000500BA73" then when node.js sends a signal with signalRef of "8EDFFE35A305EA61959701000500BA73" we know that it is Jim who has replied to our outbound SMS, because Jim's process instance is waiting for that exact signalRef (which was passed in an as input from the calling parent process) and the rest of the process logic is then "activated" by the catching intermediate event signal. We then knowe what Jim's preferred language is, and, having looked up checked-in baggage pricing that is specific to the specific airline (in this case XYZ Airlines) we send the relevant pricing information to Jim by return SMS in Jim's preferred language. This way we help Jim avoid "sticker shock" by getting stung for much higher luggage pricing - a potentially uplifting customer experience for Jim if we help him save money and stay a happy customer of both ACE and XYC. Note that the reusable sub-process that keeps running after its parent process has terminated will itself keep running until the offer (e.g. purchase check-in baggage online) will self-terminate via a timer at the appropriate time (e.g. once the original ACE Airlines flight that connects to the connecting XYC Airlines flight has departed).

We also increased the event-driven messaging to ACE Airlines departments, staff, or related parties. One such innovation is, in response to an event like a gate change, we identify passengers who may require special assistance, such as an unaccompanied minor, or a person with a disability, and let ground staff know that these people might need help getting from the old gate to the new gate, especially if a person with a disability has mobility issues.

Log in or sign up for Devpost to join the conversation.