So – thanks to my colleague Márton Sági (the AL Studio guy ;-)), I came across a quite interesting, but highly under-documented ability today in Business Central. One that makes the below post purely based on assumptions ;-), since it’s undocumented, and resides only in the platform part of Business Central (so there isn’t much code to drill down into ;-)).
Here is my assumption-based story of my expedition into the wilderness of this undocumented feature … (if that isn’t a disclaimer, I don’t know what is 🤪)
Let’s start with the conclusion in case you don’t want to spend time in reading the entire post …
The only two “real” events that I assume Microsoft wants us to use in terms of “Environment Triggers” are “OnClearCompanyConfig” and “OnClearDatabaseConfig“, since that is what they use in their application functionality.
I think we need a guideline on when and how to use this feature. I already created a discussion on ALGuidelines.Dev. You’re always welcome to join!
Error handling needs to improve – it’s hard to figure out what causes a copy-environment to go wrong. I’ll probably report this to Microsoft if I don’t get an obvious comment on this post of something I completely overlooked ;-).
Other than that – don’t forget to handle “cleanup” when copying from one environment to the other. We have these events which might be cumbersome to use, but that doesn’t make them less useful!
Before we go into it, let’s talk about some scenarios first.
In many cases, when we would copy a LIVE environment to a TEST-sandbox, we also need to be able to reset some endpoints, setup, data .. . For example: we’d need to reset Dataverse connections, or we wouldn’t want to send out emails from a sandbox to live customers, or .. . In a way: whenever an environment gets copied, you’d probably want to clean it.
In my company, we always took care of this ourselves with our own solution. Apparently, there is an out-of-the-box feature for this as well.. .
What do we have
Today, Márton pointed me to some Environment Triggers that come with the product. Even more, when you search all events for “environment”, you get:
In all honesty, I didn’t know they existed. And when you search Docs, there’s simply nothing documented about this. So the only thing to do is go old school, and dive in the code…
Where did Microsoft use this?
We all know, we get these kind of features when Microsoft need it themselves. So, when looking into the code, it turned out it exists for quite some time.
What I can see, there is only one specific “functionality” in Business Central that actually uses these triggers, and that is the “Sandbox Cleanup” which has been obsoleted and renamed to the “Environment Cleanup” functionality.
Here you can find the code on GitHub: ALAppExtensions/EnvironmentCleanupImpl.Codeunit.al (github.com)
What you can also see that the usages from the “CopyEnvironmentToSandbox” events are all being obsoleted:
After looking into it a bit more, it seems that the sole purpose of the “Environment Cleanup” module is to raise new events (the “OnClearXYZConfig”) with more “readable?” parameters by providing the “SourceType” and “Destination Type” as enums (Sandbox or Production). Very weird approach … I assume backward-compatibility is what’s happening here.. . In any case, these are events in the system-app, so I assume they are bing used in the BaseApp (and other..).
And indeed – this is what I found:
A very limited amount of places where this event is being used. But in any case, interesting to look at. For example the “Environment Cleanup Subs” (BaseApp), which contain all subscribers for all cleanup of the different modules in the BaseApp. When you explore this codeunit, you immediately see some scenarios where it can be used. Like disabling mail setup, service connections, … .
But important here is to note that actually Microsoft only uses 2 events in the application: “OnClearCompanyConfig” and “OnClearDatabaseConfig“. I assume we should use mainly these for our apps -!
Time to create my own subscribers!
I have been playing around a bit with these events. You can find the app that I have been using here:
As you can see, nothing special. Just a subscriber codeunit that attempts to subscribe to these events.
And .. I must say, it was hard to get it to work. Not because it didn’t work – simply because I made stupid mistakes that turned out to be hard to debug. Let me rephrase: it’s impossible to debug. But more on that later.
My stupid mistake was that I tried to insert data into a DataPerCompany-table while subscribing to for example the trigger “OnAfterCopyEnvironmentPerDatabase”. That obviously doesn’t work.
But also, it seemed to behave strange when I would raise and catch an error (if codeunit.run..). Something that simply works in normal code, but seems to fail the environment-copy .. 🤷🏻♂️
The real problem here is:
What to do when the copy environment fails?
Well, forget the debugger – I wouldn’t know how to attach to a session that is the copy of your environment, while it’s copying. If you can tell me – please do ;-).
The code I had simply worked when I manually invoked it, because I was obviously logged into a company, but when I copied an environment, I got this:
No reference to anything useful.
The only thing I could think of to look at was telemetry, but I could not find a single signal in my telemetry that indicated what was going wrong. Not even a trace that indicated a copy environment failed. Also, when I search through all documented Telemetry signals, I don’t find anything that indicates a (failed) environment copy – so I assume it really doesn’t exist ;-).
There is room for improvement, I’d say 😉 – at this point, troubleshooting your subscribers is a pain. The only thing I can say is: TEST before you release to production! And when testing, another thing to keep in mind is that you should make sure your extension is NOT in DEV scope, because those won’t get copied to your new environment and potentially cause problems. In stead, upload your extension through the upload page, so they are installed as a PTE extension! Very important!
Isolated Event in v20?
Since I got so many failures, I was wondering – should this happen? And since we have Isolated Events from v20 upwards, I wondered if Microsoft transferred any of these into Isolated Events (which, in my opinion, would make sense).
And they have not. Well, I don’t know if I’m right or not regarding these events being potential isolated events, but as far as I understand the topic, they are.
You don’t know what Isolated Events are? Here is the announcement: Isolated events – Dynamics 365 Release Plan | Microsoft Docs. And stay tuned – I might blog about that next time ;-).
To be honest, I wouldn’t know when these base-events (if I may call them that) are being raised – I can only assume that it’s the platform – which makes me assume (yet another assumption …) that these events actually only work in SaaS. I wouldn’t know how the OnPrem NST would be able to figure out if and when I copied a database and attached it to it – so that’s why I assume these triggers only work on SaaS.
More to come!
We have some interesting patterns that I’d like to share in the near future. So – this expedition isn’t over yet ;-).