In many cases you need to work with resources (files, scales, card readers etc.), which are available on local network/PC, from within Microsoft Dynamics 365 Business Central which runs somewhere in the Cloud. I will show you one way how to solve these things.
What is the problem?
Different processes in Business Central can need some local resources of yours. In a simples case it could be some file on your disk on your PC (or server on local network). Standard way is, that BC client will ask user to select the file which should be uploaded or select where to save downloaded file. It needs user interaction. But many automatic processes needs to run without this user interaction. E.g. to monitor some local folder for new files, read them, process them and move them to archive. You can use some Azure Storage to be able to do that in compatible way, but in some cases it is not possible, for example when the file is generated by some ancient technology or some local hardware. Still you have possibility to “synchronize” these local files to the cloud storage by some technology, but it have own problems (we were using OneDrive synchronization for this, but the reliability was very low, mainly because we needed pseudo-online updates).
Hybrid solution
To solve this problem, we can use some local running component, which have access to the local resource, and somehow connect it with the Cloud. “Standard” solution will be to have service, which offer some API. But because you need to connect from Cloud (from internet), you will need to somehow tunnel the outside incoming traffic to the local service. It will mean to create “hole” in your firewall to allow this. To limit possible security issues you can try to limit this hole for specific IPs from which the traffic will be allowed, but it is hard to do that for Business Central, because I do not know any specific IPs which are used for the BC services.
Luckily we have different Azure Services, and one of them is solving this issue - Service Bus (specifically WCF Relay). This service is allowing your service to work in “opposite” direction - your service is connecting to the cloud from inside your network. It means you only need to allow outgoing connection in your local network which is much easier (and mostly is not limited, because it is standard connection to https endpoint on internet). Azure Relay will create the public endpoint on which you can consume the API you defined in your locally running service. To implement this you need only few settings in the app.
Of course, it have some cost. You are paying some small amounts per each “relay hour” - it means for each hour your service is running and is connected to the Azure Relay (I can see standard cost 0.0090 EUR per 100 relay hours and 0.009 EUR per 10 000 messages).
Implementation
To implement this solution, you need to follow these steps:
- Implement Windows Service with Rest API with local endpoint
- Implement WCF Relay to have public endpoint
- Implement BC connector for this service
Windows Service with Rest API
How it could look like you can see here: LocalFS Service
I am not expert in c#, thus take it as a work of beginner based on examples found on internet (like this).
This windows service will open one local endpoint on port selected in the config. Second endpoint will be created through Azure WCF Relay.
Service have 3 main areas:
- REST API (contract and implementation of the API)
- Windows service handling (main program and actions to register/start/stop the service)
- Using the WCF Relay to create public endpoint
WCF Relay
To be able to connect to the locally running service from outside your local network, you need to connect it to Azure Service Bus. To be able to do this, you need to create the Relay namespace in Azure portal.
The namespace is creating the URL which is unique for your relay. The public endpoint you will need to connect to, will have name like this:
https://{RelayNameSpace}.servicebus.windows.net/{RelayServicePrefix}/{something}
WCF Relays could be of two types: Dynamics or Static. Static can be created on the portal, but we will rather use the dynamic ones. They are created and removed automatically when you start/stop your service. RelayServicePrefix in the URL is any string you will choose. In this way you can group multiple different services together. The last part of the URL is again text you choose to make the URL unique. In my example code I am using computer name and domain name to create this part (like “PC0123.mydomain.local or “PC0123.” if there is no domain).
To be able to register the service into the relay, you need to use Shared access policy key. You can get it on the Azure portal in the Shared access policies section.
When you set the values and run the service, you should see the service in the WCF Relay list on the Azure portal.
Business Central connector
To connect to the service from Business Central, use standard HTTPClient to connect to the relay address. It is standard REST API, thus it should not be a problem for you to do that. If you want to use this LocalFS service, you can use our AppSource app Navertica Local FS Connector.
I am sure that you will find many examples how to implement REST API client in AL on internet.
Security
The WCF Relay is transparent and it means it is on your service to make the authentication of the caller. In the example I am using just basic mechanism which checks that the used user name and password is same as configured one.
I am sure that there is some possibility to add security on the WCF Relay, but have not time to dig into it yet. If you have some tips, you can use the comments to share them.
Conclusion
I wanted to show you possible way how to handle things which were blockers some time ago for using Business Central Online. You can easily modify the service to not handle local files access but e.g. communicate with some locally connected hardware (special printers, scanners, scales etc.). Such a things should not prevent you now from going to cloud. It have some cost (cost of the WCF Relay), but I think it is really small cost which is overweighed by what you will get.
I know that there are other ways how you can solve such a cases, but this one is for me easy to use even with my limited knowledge. I hope it will help you to think outside the box and unblock your way.
See you in the Cloud!
Comments