The case study is a NoSQL WS that offers Read/Write possibilities for multiple databases using a REST API.
The NoSQL technology is OpenLDAP-LMDB library. It was ported from Linux to Windows and exported as a Windows DLL.
A Windows Service exposes a WS hosted by CPP REST SDK as a stand alone Web Server on a dedicated url/port. In my case, port is 7001, url is /MyServer/LMDB/.
The docker container run in Azure Container Instance using a Window Server 2016 1609 image from microsoft/iis:windowsservercore-ltsc2016.
DockerFile is:
The project is a Windows Service x64 (LMDBService.exe) who loads multiple dll :
- cpprest141d_2_10.dll
- LMDBWindowsDllD64.dll
- LMDBWrapperD64.dll
- MySharedStuffD64.dll
- Msvcp140d.dll
- Vcruntime140d.dll
- Ucrtbased.dll
The Windows service consume 2 MB of memory and PCU is always 0%. It’s the advantage of C++.
The Windows service needs to be run as administrator because cpp rest sdk require admin privileges to create the url on a port. Else ACCESS_DENIED error.
The docker image is built localy (W10) and uploaded in Azure Container Registry.
- docker image build –tag myserver6 d:devdocker
- docker login lmdbreg.azurecr.io -u lmdbreg -p XXXXXXXXXXXXXXXXXXXXXXXXXXXX
- docker tag myserver6 lmdbreg.azurecr.io/prod6
- docker push lmdbreg.azurecr.io/prod6
Azure container url : http://137.117.141.0:7001/MyServer/LMDB/request?ping
The container is up & running.
There are multiple verbs in HTTP :
- GET : get-data, set-data, ping
- POST : get-data-b64, set-data-b64
Anything else route to about.
The container use IIS to see the private log file (LMDB.txt).
Logs : http://137.117.141.0/Logs/lmdb.txt
The container use the port 7001 and writes/reads data from c:temp and c:templogs
http://137.117.141.0:7001/MyServer/LMDB/?request=ping
http://137.117.141.0:7001/MyServer/LMDB/?request=about
Sample GET requests:
INFO – 7:05:41 PM – http://137.117.141.0:7001/MyServer/LMDB/?request=set-data&key=Key_v0&value=Value_v0&name=cache_NET
INFO – 7:05:41 PM – {"key":"Key_v0","value":"Value_v0"}
INFO – 7:05:41 PM – http://137.117.141.0:7001/MyServer/LMDB/?request=get-data&key=Key_v0&name=cache_NET
INFO – 7:05:42 PM – {"key":"Key_v0","value":"Value_v0"}
For POST requests, you need code C# or JS…
Example :
private static void StoreFile(string url, string path)
{
string cache = "cache_NET";
string base_url = String.Format("http://{0}:7001/MyServer/LMDB/?request=set-data-b64&name={1}", url, cache);
var enc = System.Text.Encoding.UTF8;
string key = path;
string value = String.Empty;
byte[] buffer = File.ReadAllBytes(path);
string buffer2 = enc.GetString(buffer);
value = Base64Helper.Base64Encode(buffer2);
MakePostBuffer(base_url, value);
}
private static void MakePostBuffer(string url, string valueb64)
{
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(url);
string c = """;
string a1 = "{";
string a2 = "}";
string key = String.Format("key_{0}", DateTime.Now.Ticks);
string postData = String.Format("{1}{0}key{0}:{0}{4}{0}, {0}value{0}:{0}{3}{0}{2}", c, a1, a2, valueb64, key); // url;
//Logger.LogInfo(postData);
var data = Encoding.ASCII.GetBytes(postData);
r.Method = "POST";
r.ContentType = "application/json;";
r.ContentLength = data.Length;
r.KeepAlive = false;
using (var stream = r.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
string str = String.Format("Sending {0} bytes on {1}", data.Length, url);
Logger.LogInfo(str);
WebResponse wr = r.GetResponse();
//Logger.LogInfo(wr.ContentType);
Stream s = wr.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(s, encode);
string buffer = reader.ReadToEnd();
Logger.LogInfo(buffer);
reader.Close();
wr.Close();
}
Christophe Pichaud
Leave a Reply