TIL: Built-in file compare in Visual Studio Code

Note: “TIL” posts are short on purpose. They are meant as a quick way to share something I learned or found. This might be something trivial to some people, but they are new to me. TIL stands for Today I Learned.

Today I was editing a Swagger file with Visual Studio Code. I was looking for an extension to be able to compare two files with each other. They were not in source control, so I was not able to use that…

I found that comparing files is actually built-in into Visual Studio Code!

Just right-click your first file and click “Select for Compare”.
Then, right-click your second file and select “Compare ‘file1’ with ‘file2′”.

So, no need for extra extensions, just provided straight out of the box.

Advertisements

The BizTalk Purge & Archive Job now supports clean-up of orphaned instances

With the latest CU’s for BizTalk Server, the Purge and Archive job can now be configured to clean up orphaned instances. The biggest advantage is that the cleanup is done without any downtime…. yes this means you no longer need to run the BizTalk Health Monitor to clean them up!

The change was marked in the following Microsoft Support article: Orphaned BizTalk DTA service instances are not removed by the “DTA Purge and Archive” job in BizTalk Server

The change is included in the following cumulative update packages:

Once you apply the CU to your servers, you will notice an additional parameter in the BizTalk DTA Purge and Archive SQL job: @fHardDeleteRunningInstances

If you would like to use the new behavior to clean-up the orphaned instances at run-time, you would need to set the parameter to 1, as displayed below:

exec dtasp_PurgeTrackingDatabase

1, –nLiveHours

30, –nLiveDays

7,  –nHardDeleteDays​

\\myserver\mybackupfolder, –nvcFolder

null, –nvcValidatingServer

0 , –fForceBackup

— fHardDeleteRunningInstances ​

Once set, the job will start removing any orphaned instances older than the @nHardDeleteDays parameter.

Keep in mind:

  • CU’s should be thoroughly tested on DEV, TEST and ACCeptance environments, before migrating your production servers.
  • It is still considered good practice to keep your scripts/setup in BizTalk Health Monitor. Regularly scan your system(s) to make sure everything is running smoothly.

Corrupt BizTalk orchestrations

Every now and then, when dealing with BizTalk orchestrations, you might encounter issues you can’t explain. Things like the following, infamous error, may occur without any valid reason:

#error: Errors exist for one or more children

Even after fixing every error, you rebuild the project and/or solution, and the error is still not fixed…

I had this issue a couple of times now to be able to recognize the exact behavior… There actually may be nothing wrong with your logic BizTalk orchestration, in fact something may be wrong with the code behind.

Opening your orchestration with the Visual Studio text editor (right click the odx file and choose ‘Open with…’:

corrupt2

In the generated code in the bottom part of the .odx file, you may find the following culprit:

corrupt1

What seems to happen is that, during compilation, Visual Studio will detect an error in your orchestration, but for some reason ends up adding the compiler error into your code.
After fixing the issue in your orchestration and recompiling, the issue persists, because the compiler somehow refuses to remove the error from the code. And thus a Rebuild always results in the same error.

Workaround

An odx file actually consists out of the following structure:

#if __DESIGNER_DATA
#error Do not define __DESIGNER_DATA.
<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<om:MetaModel MajorVersion=”1″ MinorVersion=”3″ ……
………..
……….
</om:Element>
</om:MetaModel>
#endif // __DESIGNER_DATA
[Microsoft.XLANGs.BaseTypes.BPELExportable(false)]
module MyNamespace.MyOrchestration
{
internal messagetype myMsg
….
….
….
}

As you can see, the first part is “DESIGNER_DATA“. This part actually contains an XML representation of your orchestration. The size, shape and position of all of your shapes for example, each of their ID’s, the code you’ve written into expression shapes, etc….

After that part comes the generated code, which is written by Visual Studio each time your orchestration gets recompiled/rebuilt.

The trick is to remove the part after the following line:

#endif // __DESIGNER_DATA

Then, open the orchestration in the designer and make any change to it.

This will force the compiler to regenerate the code from scratch, which results in a correct version of the code (without the #error in it).
Another way would be to remove the line where the #error is in, but I find it safer to let it regenerate everything.

This should fix the issues you have while recompiling/rebuilding the BizTalk orchestration.

One more thing:
Once you opened an .odx file via the Visual Studio Text/XML Editor, you ‘ll need to fix your BizTalk project or your orchestration will always open that editor on double-click, instead of the BizTalk orchestration designer.
Find out how to do this in a blog post I wrote, dealing with just that issue.

Hope this helps! Let me know if it did!
Cheers, Pieter

BizTalk orchestration keeps opening in Visual Studio text editor

You may know the issue when opening a BizTalk orchestration and it opens like this:

orcheditor1
Note: I blurred the code to protect the name of my client.

Not much you can do about it, except right-clicking the orchestration and clicking ‘Open With…’ and choosing the BizTalk Orchestration Designer.

orcheditor2

However, if you close the BizTalk Orchestration Designer again, and double-click the odx file, it once again opens in the first, yet useless, view.

An easy fix

The culprit is actually not in the orchestration, but can be found in the BizTalk project (.btproj) file:

Open the Visual Studio BizTalk project (.btproj file) containing the orchestration with your favorite editor and search for ‘Designer’:

orcheditor3

You’ll notice that the orchestration, which refuses to open in the Orchestration Designer, actually has a node SubType which is set to “Designer“.

Now remove the line containing this node from the file in your editor, save the file and reload the file in Visual Studio.
If you now double-click the orchestration, it now opens in the BizTalk Orchestration Designer again!

Don’t forget to check-in/commit your changes 😉

Hope this helps! Cheers!
Pieter

A CrazyBizTalk confession

logo

Introduction

(This blog post was co-written by Pieter VandenheedeGlenn Colpaert, both colleagues at Codit)

We finally admit it… we both were the brains behind the CrazyBizTalk account. There… it’s in the open. After Integrate 2017, day 3, we were no longer able to keep it a secret, so there is no use of denying it anymore…

It was a fun ride, which started in 2013 already. We’ve written this post to give you some insights on how it all got started, the fun we had through the years and what the next steps are.

How it all started

In May 2013, both of us were very actively developing BizTalk applications. The Microsoft Integration community was starting to become a vibrant place and the #msbts Twitter hashtag (for Microsoft BizTalk Server) became a thing we both started following on a daily basis.

Now and then we were making fun of BizTalk items and the very first tweet Glenn sent out was the following:

It was also the birth of our very own hashtag: #crazybiztalktweets!2

We both thought it would be a great idea to start a Twitter account and several minutes later, Pieter registered the Twitter account CrazyBizTalk, a name inspired by the moment.

We thought of things to do and after a few days of brainstorming, we decided we had our first few memes and quotes we could start with.

The very first tweet from the CrazyBizTalk account was on May 27th, 2013:

It didn’t get a lot of love back then, but we felt it was funny, so we decided to amp things up and put up some more tweets in the days to come, this time including the meme pictures:

It was fun, but still it was something casual after those few first days. Thought to be forgotten at some point. However, it clicked with us. We discussed the next steps, proposed new quotes, confirmed or vetoed others. We had some good laughs and giggles, every time we came up with something new.

At some point we even created a DropBox shared folder, in order to keep up with the new ideas and memes we had… and yes, we even had some BizTalk lyrics…

5

They were good times, but neither of us had thought we would keep going 4 years later.

Some “glorious” moments

Time went by and we started getting 100+ followers on Twitter and getting more every time we made up something new. People started liking, re-tweeting (RT’ing), we even had some private messages from time to time… you know who you were 😉

Some of our best moments were at Integrate 2013, 2015 and 2017.
Audiences hooked on Twitter with a single #integrate hashtag are all potential followers we discovered. Here’s a selection from the past years:

Admittedly, we sometimes made fun of our beloved BizTalk Server. Being anonymous gives you the advantage of being able to say what you want. We realized we had to be very careful in what to say, in order not to burn the account. However, we did notice that whenever we approached the acceptable line, we did get more likes and RT’s than usual!

Some other things to know:

  • We have amassed a 700+ followers. Not bad considering this is a parody account for a Microsoft Server product considered “dead” to some, and in such a specialty domain.
  • We had likes and RT’s from some interesting people/accounts.
    • Josh Twist when he was Program Manager for BizTalk Server for a while.
    • The official BizTalk Server account.
    • etc…
  • At some point, we owned a website: crazybiztalk.azurewebsites.net, but due to an error in the hosting, we had to close it again with a corrupt database.
  • Some of our colleagues knew who we were, but we made them vow not to tell anyone. We still have a lot of people in the company who don’t know.
    It’s so much fun having colleagues show you the funny tweet they just saw on Twitter, not knowing you just posted it a few seconds earlier! 🙂
  • At some points in time there were only one of us posting to the account.
  • During Integrate 2015 we were too busy writing blog posts for our company blog and didn’t feel we were able to post anonymously enough. We did not tweet during that conference.
  • During Integrate 2017, day 1, we actually won a book for having the most popular tweet that day. On day 2, we were about to do the same, but Nick Hauenstein won with a tweet from the day before 😉
  • At some point, somebody created a CrazyAzure Twitter account! Whoever you are, you are awesome! 🙂

Also, over time, people always tried to figure out who was behind the account…
A special thanks to the following people,  who made this a very fun experience:

7

Also, people gave us some praise now and then, which was much appreciated!

The cover blown

A few years ago, Glenn was already considered as being the only person behind the account. A few months later however, speculation started again, as the account started posting at conferences while Glenn not being present. A few years later however, disaster struck.

Integrate 2017, day 3 will be marked as a black page in our book. The conference was a BIG HIT so far: we won a book on the first day due to the most popular #integrate2017 tweet. Appeared during a demo of SteefJan on the second day and tweets were getting a lot of likes and love.

During one of the last sessions however, while trying to appear in yet another demo, things went downhill when we used Tweetdeck to post (too) quickly. Pieter forgot to uncheck his own account and posted. Only to be followed by:

The damage was done and the secret identity broken… What a pity!!

Could you have known?

Is there any way you could have known it was us or related to us?

Sure, there were some clues we were not able to hide:

  • The first two followers of the account were both of our Twitter accounts. There was no option to remove them (unfortunately).
  • The first 7 followers were Codit Belgium accounts.
  • We always posted during hours comparing with the Belgian timezone

Conclusion: What’s next?

There is no next… unfortunately.

We have both decided to quit the account.
Although it is tempting to continue with the account, it would no longer be the same as it was. Now that we are affiliated with the account, we feel people may become biased by what we think is funny. It was very fun doing what we did however.

We will close the account and login now and then, to make sure the tweets are preserved for any new BizTalk developer that happens to stumble upon them.

We very much enjoyed doing what we did and truly hoped to have made you laugh, giggle or just sparked an interest into what we did. We did not spend a lot of time on it, but we felt like making things better by adding a little humor.

Let us know what you think!
What was your favorite one? How did you experience all of this?

CLOSURE

Cheers! #crazybiztalktweets

Glenn Colpaert & Pieter Vandenheede

Azure API Management: subscription key invalid

download

Azure API Management is awesome! The thought of API virtualization and the power, flexibility and ease-of-use it can bring, is impressive to say the least.

I have the chance to ‘play’ with the technology with a project I’m working on for one particular client. Starting to play with things you often miss the simplest details or take things for granted. This is such a story…

So, I went on to set-up an API, provided some operations, configured security, etc…

However, using Postman, one error I kept getting was the following:

{ “statusCode”: 401, “message”: “Access denied due to invalid subscription key. Make sure to provide a valid key for an active subscription.” }

No matter what I did, I kept getting the error. Removing the Ocp-Apim-Subscription-Key in the header, provided me with the following error:

{ “statusCode“: 401, “message“: “Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API.” }

It was clear I needed to provide the Azure APIM subscription key, but I was providing the wrong one it seems.

It’s already tricky to find your subscription keys and I had to ask some colleagues more than once where to retrieve it.

To retrieve your keys, go to the Azure portal, select your API Management service, select Users (the below picture mentions Users – PREVIEW, since the transition to the current portal is not finished yet) and you’ll find your subscription keys for your “products” there.

APIM1

One of the things about Azure API Management is  that any developer can subscribe to start using your API. This can be a paying customer or a customer which you just need to register. For that, there is the Azure API Management developer portal. A completely customizable portal with developer documentation, test forms, etc… based on the settings you determine in the administration portal.

In Azure API Management, a Product contains one or more APIs as well as a usage quota and the terms of use. Once a product is published, developers can subscribe to the product and begin to use the API’s which are part of the product’.

This time, from the developer portal, I copied the subscription keys and added a new header “Ocp-Apim-Subscription-Key”, containing the key copied from the Azure portal.

APIM2

Still, I kept getting the same error…. it kept me busy for far too long… until I tried to call the Echo API. This is the default API, provided with any Azure API Management service.
I noticed, when trying to call this API from within the developer portal, that the header was already provided. I did not have to provide it myself for the Echo API

APIM3

Then it dawned to me: I didn’t bother to add my API to one of the (default) products! In the API configuration, you can see in which products your API is included:

APIM4

I quickly included my API into the Starter and Unlimited products and saved.

APIM5

Seconds later, refreshing the developer portal for my own API gave me the following result:

APIM3

Now, sitting here and writing this up, I still don’t have my API working, but at least some poor soul will perhaps some day have the same issue and find this page.

Lesson learned

Always add your API to your product()s, or you will not be able to call them.

 

Hope this helps at least someone, since I didn’t find this within the MANY Google searches I performed.

Cheers,
Pieter

Saving time via Logic Apps: a real world example

Introduction

At Codit, I manage the blog. We have some very passionate people on board who like to invest their time to get to the bottom of things and – also very important – share it with the world!
That small part of my job means I get to review blog posts before publishing on a technical level. It’s always good to have one extra pair of eyes reading the post before publishing it to the public, so this definitely pays off!

An even smaller part of publishing blog posts is making sure they get enough coverage. Sharing them on Twitter, LinkedIn or even Facebook is part of the job for our devoted marketing department! And analytics around these shares on social media definitely come in handy! For that specific reason we use Bitly to shorten our URLs.
Every time a blog post gets published, someone needed to add them manually to out Bitly account and send out an e-mail. This takes a small amount of time, but as you can imagine it accumulates quickly with the amount of posts we generate lately!

Logic Apps to the rescue!

I was looking for an excuse to start playing with Logic Apps and they recently added Bitly as one of their Preview connectors, so I started digging!

First, let’s try and list the requirements of our Logic App to-be:

Must-haves:

  • The Logic App should trigger automatically whenever a new blog post is published.
  • It should create a short link, specifically for usage on Twitter.
  • It also should create a short link, specifically for LinkedIn usage.
  • It should send out an e-mail with the short links.
  • I want the short URLs to appear in the Bitly dashboard, so we can track click-through-rate (CTR).
  • I want to spend a minimum of Azure consumption.

Nice-to-haves:

  • I want the Logic App to trigger immediately after publishing the blog post.
  • I want the e-mail to be sent out to me, the marketing department and the author of the post for (possibly) immediate usage on social media.
  • If I resubmit a logic app, I don’t want new URLs (idempotency), I want to keep the ones already in the Bitly dashboard.
  • I want the e-mail to appear as if it was coming directly from me.

Logic App Trigger

I could easily fill in one of the first requirements, since the Logic App RSS connector provides me a very easy way to trigger a logic app based on a RSS feed. Our Codit blog RSS feed seemed to do the trick perfectly!

Now it’s all about timing the polling interval: if we poll every minute we get the e-mail faster, but will spend more on Azure consumption since the Logic App gets triggered more… I decided 30 minutes would probably be good enough.

2017-06-09 00_30_33-Logic Apps Designer - Microsoft Azure

Now I needed to try and get the URL for any new posts that were published. Luckily, the links – Item provides me the perfect way of doing that. The Logic Apps designer conveniently detects this might be an array of links (in case two posts get published at once) and places this within a “For each” shape!

2017-06-09 00_33_34-Logic Apps Designer - Microsoft Azure

Now that I had the URL(s), all I needed to do was save the Logic App and wait until a blog post was published to test the Logic App. In the Logic App “Runs history” I was able to click through and see for myself that I got the links array nicely:

2017-06-09 00_40_08-Logic app run - Microsoft Azure

Seems there is only one item in the array for each blog post, which is perfect for our use-case!

Shortening the URL

For this part of the exercise I needed several things:

  • I actually need two URLs: one for Twitter and one for LinkedIn, so I need to call the Bitly connector twice!
  • Each link gets a little extra information in the query string called UTM codes. If you are unfamiliar with those, read up on UTM codes here. (In short: it adds extra visibility and tracking in Google Analytics).
    So I needed to concatenate the original URL with some static UTM string + one part which needed to be dynamic: the UTM campaign.

For that last part (the campaign): we already have our CMS cleaning up the title of a blog post in the last part of the URL being published! This seems ideal for us here.

However, due to lack of knowledge in Logic Apps-syntax I got so frustrated and created an Azure Function to do just that (extract the interesting part from the URL):

2017-06-09 00_49_30-Logic app run - Microsoft Azure

I wasn’t pleased with this, but at least I was able to get things running…
It however meant I needed extra, unwanted, Azure resources:

  • Extra Azure storage account (to store the function in)
  • Azure App Service Plan to host the function in
  • An Azure function to do the trivial task of some string manipulation.

After some additional (but determined) trial and error late in the evening, I ended up doing the same in a Logic App Compose shape! Happy days!

2017-06-09 00_52_35-Logic Apps Designer - Microsoft Azure

It takes the URL, splits it into an array, based on the slash (‘/’) and takes the part which is interesting for my use-case. See for yourself:

2017-06-09 00_55_30-Logic app run - Microsoft Azure

Now I still needed to concatenate all pieces of string together. The concat() function seems to be able to do the trick, but an even easier solution is to just use another Compose shape:

2017-06-09 00_56_35-Logic Apps Designer - Microsoft Azure - Twitter2017-06-09 00_56_49-Logic Apps Designer - Microsoft Azure - LinkedIn

Concatenation comes naturally to the Compose shape!

Then I still needed to create the short links by calling the Bitly connector:

2017-06-09 00_59_33-Logic Apps Designer - Microsoft Azure - Bitly

Let’s send out an e-mail

Sending out e-mail, using my Office365 account is actually the easiest thing ever:

2017-06-09 01_00_45-Logic Apps Designer - Microsoft Azure - Mail

Conclusion

My first practical Logic App seems to be a hit! And probably saves us about half an hour of work every week. A few hours of Logic App “R&D” will definitely pay off in the long run!

Here’s the overview of my complete Logic App:

2017-06-09 01_01_41-Logic Apps Designer - Microsoft Azure - Complete Logic App.png

Some remarks

During development however, I came across – what appear to me – some limitations :

  • The author of the blog post is not in the output of the RSS connector, which is a pity! This would have allowed me to use his/her e-mail address directly or, if it was his/her name, to look-up the e-mail address using the Office 365 users connector!
  • I’m missing some kind of expression shape in Logic Apps!
    Coming from BizTalk Server where expression shapes containing a limited form of C# code are very handy in a BizTalk orchestration, this is something that should be included one way or the other (without the Azure function implementation).
    A few lines of code in there is awesome for dirty work like string manipulation for example.
  • It took me a while to get my head around Logic Apps syntax.
    It’s not really explained in the documentation when or when not to use @function() or @{function()}. It’s not that hard at all once you get the hang of it. Unfortunately it took me a lot of save errors and even some run-time errors (not covered at design time) to get to that point. Might be just me however…
  • I cannot rename API connections in my Azure Resource Group. Some generic names like ‘rss’, ‘bitly’ and ‘office-365’ are used. I can set some properties so they appear nicely in the Logic App however.
  • We have Office365 Multi-Factor Authentication enabled at our company. I can authorize the Office365 API connection, but this will only last for 30 days. I might need to change to an account without multi-factor authentication if I don’t want to re-authorize every 30 days…

Let me know what you think in the comments! Is this the way to go?
Any alternative versions I could use? Any feedback is more than welcome.

In a next blog post I will take some of our Logic Apps best practices to heart and optimize the Logic App.

Have a nice day!
Pieter