public async Task PostAsync()

in edge-modules/metrics-collector/src/FixedSetTableUpload/AzureFixedSetTable.cs [54:154]


        public async Task<bool> PostAsync(string workspaceId, string sharedKey, string content, string ArmResourceId)
        {
            Preconditions.CheckNotNull(workspaceId, "Workspace Id cannot be empty.");
            Preconditions.CheckNotNull(sharedKey, "Workspace Key cannot be empty.");
            Preconditions.CheckNotNull(content, "Fixed set table content cannot be empty.");

            try
            {
                // Lazily generate and register certificate.
                if (cert == null)
                {
                    (X509Certificate2 tempCert, (string certString, byte[] certBuf), string keyString) = CertGenerator.RegisterAgentWithOMS(workspaceId, sharedKey, Constants.DefaultLogAnalyticsWorkspaceDomainPrefixOms);
                    cert = tempCert;
                }
                using (var handler = new HttpClientHandler())
                {
                    handler.ClientCertificates.Add(cert);
                    handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
                    handler.PreAuthenticate = true;
                    handler.ClientCertificateOptions = ClientCertificateOption.Manual;

                    Uri requestUri = new Uri("https://" + workspaceId + Constants.DefaultLogAnalyticsWorkspaceDomainPrefixOds + Settings.Current.AzureDomain + "/OperationalData.svc/PostJsonDataItems");

                    using (HttpClient client = new HttpClient(handler))
                    {
                        client.DefaultRequestHeaders.Add("x-ms-date", DateTime.Now.ToString("YYYY-MM-DD'T'HH:mm:ssZ"));  // should be RFC3339 format;
                        client.DefaultRequestHeaders.Add("X-Request-ID", Guid.NewGuid().ToString("B"));  // This is host byte order instead of network byte order, but it doesn't mater here
                        client.DefaultRequestHeaders.Add("User-Agent", "IotEdgeContainerAgent/" + Constants.VersionNumber);
                        client.DefaultRequestHeaders.Add("x-ms-AzureResourceId", ArmResourceId);

                        // TODO: replace with actual version number
                        client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("IotEdgeContainerAgent", Constants.VersionNumber));

                        // optionally compress content before sending
                        int contentLength;
                        HttpContent contentMsg;
                        if (Settings.Current.CompressForUpload)
                        {
                            byte[] withHeader = ZlibDeflate(Encoding.UTF8.GetBytes(content));
                            contentLength = withHeader.Length;

                            contentMsg = new ByteArrayContent(withHeader);
                            contentMsg.Headers.Add("Content-Encoding", "deflate");
                        }
                        else
                        {
                            contentMsg = new StringContent(content, Encoding.UTF8);
                            contentLength = ASCIIEncoding.Unicode.GetByteCount(content);
                        }

                        if (contentLength > 1024 * 1024)
                        {
                            LoggerUtil.Writer.LogDebug(
                                "HTTP post content greater than 1mb" + " " +
                                "Length - " + contentLength.ToString());
                        }

                        contentMsg.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                        var response = await client.PostAsync(requestUri, contentMsg).ConfigureAwait(false);
                        var responseMsg = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                        LoggerUtil.Writer.LogDebug(
                            ((int)response.StatusCode).ToString() + " " +
                            response.ReasonPhrase + " " +
                            responseMsg);

                        if ((int)response.StatusCode != 200)
                        {
                            failurecount += 1;

                            if (DateTime.Now - lastFailureReportedTime > TimeSpan.FromMinutes(1))
                            {
                                LoggerUtil.Writer.LogDebug(
                                    "abnormal HTTP response code - " +
                                    "responsecode: " + ((int)response.StatusCode).ToString() + " " +
                                    "reasonphrase: " + response.ReasonPhrase + " " +
                                    "responsemsg: " + responseMsg + " " +
                                    "count: " + failurecount);
                                failurecount = 0;
                                lastFailureReportedTime = DateTime.Now;
                            }

                            // It's possible that the generated certificate is bad, maybe the module has been running for a over a month? (in which case a topology request would be needed to refresh the cert).
                            // Regen the cert on next run just to be safe.
                            cert = null;
                        }
                        return ((int)response.StatusCode) == 200;
                    }
                }
            }
            catch (Exception e)
            {
                LoggerUtil.Writer.LogError(e.Message);
                if (e.InnerException != null)
                {
                    LoggerUtil.Writer.LogError("InnerException - " + e.InnerException.Message);
                }
            }

            return false;
        }