Quote of the day :
“Nothing can stop the man with the right mental attitude from achieving his goal; nothing on earth can help the man with the wrong mental attitude.”
Thomas Jefferson
Quote of the day :
“Nothing can stop the man with the right mental attitude from achieving his goal; nothing on earth can help the man with the wrong mental attitude.”
Thomas Jefferson
I’ve been receiving email from Sabre regarding Payment Card Industry (PCI) TLS v1.2 security deadlines and Sabre’s High Availability (HA) infrastructure. (Sabre has introduced new URLs for use with Sabre APIs).
I’ve navigated a maze of URLs and PDFs from Sabre. The majority of these were not helpful to me but I muddled through and reduced the upgrade process to a few steps. Note that these steps handle both the high availability URL updates and the TLS v1.2 updates.
The steps below are accomplished using Visual Studio Professional 2017. If you’re not using it yet, you should be.
Step 1 – Update to use the High Availability URLs
In VS, Find and Replace in the entire solution (*.cs files only)
From this : https://webservices.sabre.com
To this : https://webservices.havail.sabre.com
At this point, I tried to run against the new HA URLs .. but no luck, here’s the error:
Exception Message : The request was aborted: Could not create SSL/TLS secure channel.
Step 2 – Update to the .NET Framework 4.6.1
I updated ALL of my projects to .NET Framework 4.6.1, this handles the TLS v1.2 upgrade.
Step 3 – Recompile and Run
Nothing else to do, I’m running now with the new HA URLs and also using TLS v1.2.
I saw this on the local news the other day… a report on a new FB feature. WTF?! Why is this newsworthy?
It makes me nuts to see the news “go to social media”… how is this news? How is garbage that random people post/tweet ever newsworthy?
Same goes for any celebrity – why does the news have to “report” this nonsense? I don’t care what they have to say on social media! If I cared, I would follow them on whichever social media outlet they spout their nonsense. This is not news! Please let TMZ handle the lowest common denominator.
Quote of the day :
I heard this a few days ago, had a chuckle but don’t think I really got it at the time. Here’s a good blog post explaining what it means.
Quote of the day :
I’m thankful that my house is OK.
Summary: Sabre TravelItineraryReadService TravelItineraryReadRQ version 2.2.0 returns incomplete Seat data. TravelItineraryReadRQ version 3.4.0 returns all of the Seat data.
I had bug in my PNR capture code – it was throwing an exception on my persist flight details stored procedure call because I wasn’t giving it a required seat number. It was a trivial code fix, I needed to pass an empty string to the stored procedure (not a null value).
But did I have a bug further upstream in my TravelItineraryReadRS parsing and mapping code? Or is the data really missing?
My current version of the TravelItineraryReadService is using TravelItineraryReadRQ version 2.2.0. Below is the snippet from the TravelItineraryReadRS. You can see that it’s only returning a seat number for segment 2, all of the other segments have no value for the seat number – the attribute is missing entirely. So I don’t have any parsing/mapping issues, sabre isn’t giving me the data.
<TravelItineraryReadRS Version="2.2.0"> ... <Seats> <Seat NameNumber="01.01" SegmentNumber="0001" Status="HRQ"> <FlightSegment> <DestinationLocation LocationCode="PHX" /> <OriginLocation LocationCode="SBA" /> </FlightSegment> </Seat> <Seat Changed="N" NameNumber="01.01" Number="04A" SegmentNumber="0002" SegmentStatus="HK" SmokingPreference="N" Status="HRS" TypeTwo="WLMI"> <FlightSegment> <DestinationLocation LocationCode="ORD" /> <OriginLocation LocationCode="PHX" /> </FlightSegment> </Seat> <Seat NameNumber="01.01" SegmentNumber="0003" Status="HRQ"> <FlightSegment> <DestinationLocation LocationCode="PHX" /> <OriginLocation LocationCode="ORD" /> </FlightSegment> </Seat> <Seat NameNumber="01.01" SegmentNumber="0004" Status="HRQ"> <FlightSegment> <DestinationLocation LocationCode="SBA" /> <OriginLocation LocationCode="PHX" /> </FlightSegment> </Seat> </Seats> ... </TravelItineraryReadRS> |
I’m in the middle of evaluating (and implementing) TravelItineraryReadRQ version 3.4.0. Cool, it has my seat data! Maybe I need to roll this into production sooner than planned…
<TravelItineraryReadRS Version="3.4.0"> ... <Seats> <Seat Changed="N" NameNumber="01.01" Number="02A" SegmentNumber="0001" SegmentStatus="PN" SmokingPreference="N" Status="HRS" TypeTwo=""> <FlightSegment> <DestinationLocation LocationCode="PHX" /> <OriginLocation LocationCode="SBA" /> </FlightSegment> </Seat> <Seat Changed="N" NameNumber="01.01" Number="04A" SegmentNumber="0002" SegmentStatus="HK" SmokingPreference="N" Status="HRS" TypeTwo="WLMI"> <FlightSegment> <DestinationLocation LocationCode="ORD" /> <OriginLocation LocationCode="PHX" /> </FlightSegment> </Seat> <Seat Changed="N" NameNumber="01.01" Number="03A" SegmentNumber="0003" SegmentStatus="PN" SmokingPreference="N" Status="HRS" TypeTwo=""> <FlightSegment> <DestinationLocation LocationCode="PHX" /> <OriginLocation LocationCode="ORD" /> </FlightSegment> </Seat> <Seat Changed="N" NameNumber="01.01" Number="03F" SegmentNumber="0004" SegmentStatus="PN" SmokingPreference="N" Status="HRS" TypeTwo=""> <FlightSegment> <DestinationLocation LocationCode="SBA" /> <OriginLocation LocationCode="PHX" /> </FlightSegment> </Seat> </Seats> ... </TravelItineraryReadRS> |
I recently had to implement 2 changes to a winforms application I’m working on, here’s the general requirements:
I searched google and found a bunch of helpful sources for both, this is a melding of several of them to fit my needs.
Here are the guts of the winform that deals with the notifyIcon:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | using System; using System.Windows.Forms; namespace SingletonAppWithNotifyIcon { public partial class MainForm2 : Form { private bool IsQuit { get; set; } public MainForm2() { InitializeComponent(); } private void MyFormClosing(object sender, FormClosingEventArgs e) { if (IsQuit) return; HideMe(); e.Cancel = true; } private void HideMe() { Hide(); } public void ShowMe() { WindowState = FormWindowState.Normal; Visible = true; Activate(); } private void QuitMe() { IsQuit = true; Application.Exit(); } private void MainForm2_Load(object sender, EventArgs e) { notifyIcon1.ContextMenu = new ContextMenu(); notifyIcon1.ContextMenu.MenuItems.Add(new MenuItem("Quit My Fancy App", NotifyIconQuit)); } private void NotifyIconQuit(object sender, EventArgs e) { QuitMe(); } private void NotifyClick(object sender, EventArgs e) { ShowMe(); } private void CloseClick(object sender, EventArgs e) { HideMe(); } private void QuitClick(object sender, EventArgs e) { QuitMe(); } } } |
Here the highlights for the singleton application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | using System; using System.Windows.Forms; using Microsoft.VisualBasic.ApplicationServices; namespace SingletonAppWithNotifyIcon { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); SingleInstanceAppStarter.Start(new MainForm2(), StartNewInstance); } static void StartNewInstance(object sender, StartupNextInstanceEventArgs e) { var forms = Application.OpenForms; var frm = forms["MainForm2"] as MainForm2; if (frm != null) { frm.ShowMe(); } else { var f = new MainForm2(); f.ShowDialog(); } } } class SingleInstanceApp : WindowsFormsApplicationBase { public SingleInstanceApp() { } public SingleInstanceApp(Form f) { IsSingleInstance = true; MainForm = f; } } public class SingleInstanceAppStarter { static SingleInstanceApp _app; public static void Start(Form f, StartupNextInstanceEventHandler handler) { if (_app == null && f != null) { _app = new SingleInstanceApp(f); } if (_app == null) return; _app.StartupNextInstance += handler; _app.Run(Environment.GetCommandLineArgs()); } } } |
Here’s a sample solution (nice and simple) for you to download and experiment with…
SingletonAppWithNotifyIcon.zip