HttpClient exception in Windows service, but not in WinForms and Console application - async-await

I am experiencing an issue where an async call works in my WinForms and Console test applications, but not when I implement the same code in my intended target format - a Windows service.
I always get the "A task was canceled" exception - and I can't figure out why :|
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TotalArchiveService.CustomerServices.<ValidateCustomerCoreWSGen2>d__2.MoveNext() in C:\DeveloperArea\Dev\src\TotalArchiveService\CustomerServices.cs:line 123
Using Fiddler, I can see that the Windows service doesn't even call the service. At least there are no traces of it in the Fiddler log.
The following are code examples, where the two first ones are the WinForms and Console variants respectively. The last on is the non functioning Windows service.
In the Windows Service, the ValidateCustomer method is called in the OnElapsedTime method of the Windows service. I have tried several intervals, as I suspected that there were some kind of overlap of calls due to the async here, but it doesn't change anything. Even if it had been, I'd thought that I'd seen some traces of the first call in Fiddler, but there's nothing.
I am using .NET Framework 4.8 for the service and WinForms variants. .NET 6.0 for the Console app.
Any help or suggestions would be greatly appreciated.
WinForms
private static async Task<string> ValidateCustomerCoreWSGen2(string customerNumber)
{
REMOVED SECTION WHERE INTERNAL PARAMS WERE UPDATED FROMN CONFIG.
}
catch (Exception _ex)
{
_status = "CONFIG_ERROR";
}
try
{
using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(_timeout) })
{
// Create HTTP request.
var customerBuilder = new UriBuilder(new Uri($"{_endpoint}"));
var customerRequest = new HttpRequestMessage(HttpMethod.Post, customerBuilder.Uri);
// Set SOAP action
customerRequest.Headers.Add("SOAPAction", "");
// SOAP body content
string xmlSOAP = GetXmlSOAP("CUSTOMERREAD", _sourceApplication, _destinationApplication, _function, _version, _username, _channel, _orgId, _orgUnit, customerNumber);
customerRequest.Content = new StringContent(xmlSOAP, Encoding.UTF8, "text/xml");
// Add signature headers to request object
await SignHttpRequestMessage(customerRequest);
// Call service
var customerResponse = await client.SendAsync(customerRequest);
//Response handling
if (customerResponse.IsSuccessStatusCode)
{
// Do what you want with response body
var responseBody = await customerResponse.Content.ReadAsStringAsync();
_status = "CUSTOMER_EXISTS";
}
else
{
_status = "CUSTOMER_READ_EXCEPTION";
var responseBody = await customerResponse.Content.ReadAsStringAsync();
var message = $"Response returned with status {customerResponse.StatusCode}. Reason: {customerResponse.ReasonPhrase}";
}
}
}
catch (Exception _ex)
{
_status = "SERVICE_ERROR";
}
return _status;
}
static async Task SignHttpRequestMessage(HttpRequestMessage request)
{
// externalize configuration of these
string certPath = "";
string keyStorePassword = "";
string keyId = "";
certPath = Path.GetFullPath(#"c:\cert2\cert.pfx"); // path to keystorefile
keyStorePassword = "REMOVED";
keyId = "REMOVED";
X509Certificate2Collection certs = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(certPath, keyStorePassword, X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.Exportable);
var services = new ServiceCollection()
.AddHttpMessageSigning()
.UseKeyId(keyId)
.UseSignatureAlgorithm(SignatureAlgorithm.CreateForSigning(cert, HashAlgorithmName.SHA256))
.UseDigestAlgorithm(HashAlgorithmName.SHA256)
.UseUseDeprecatedAlgorithmParameter()
.UseNonce(false)
.UseHeaders()
.Services;
using (var serviceProvider = services.BuildServiceProvider())
{
using (var signerFactory = serviceProvider.GetRequiredService<IRequestSignerFactory>())
{
var requestSigner = signerFactory.CreateFor(keyId);
await requestSigner.Sign(request);
}
}
request.Headers.Add("Signature", request.Headers.Authorization.ToString());
request.Headers.Authorization = null;
}
private static string GetXmlSOAP(string method, string sourceApplication, string destinationApplication, string function, string version, string username, string channel, string orgId, string orgUnit, string customerNumber)
{
string _xmlSOAP = "";
if (method.ToUpper() == "CUSTOMERREAD")
{
_xmlSOAP = #"<?xml version=""1.0"" encoding=""utf-8""?>
<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:wsc=""http://REMOVED""
xmlns:urn=""urn:REMOVED""
xmlns:urn1=""urn:REMOVED""
xmlns:urn2=""urn:REMOVED"">
<soapenv:Header>
<wsc:AutHeader>
<wsc:SourceApplication>" + sourceApplication + #"</wsc:SourceApplication>
<wsc:DestinationApplication>" + destinationApplication + #"</wsc:DestinationApplication>
<wsc:Function>" + function + #"</wsc:Function>
<wsc:Version>" + version + #"</wsc:Version>
<wsc:ClientContext>
<wsc:userid>" + username + #"</wsc:userid>
<wsc:credentials/>
<wsc:channel>" + channel + #"</wsc:channel>
<wsc:orgid>" + orgId + #"</wsc:orgid>
<!--Optional:-->
<wsc:orgunit>" + orgUnit + #"</wsc:orgunit>
<!--Optional:-->
<wsc:customerid>" + customerNumber + #"</wsc:customerid>
<!--Optional:-->
<wsc:locale>no_NO</wsc:locale>
<wsc:ip>127.0.0.1</wsc:ip>
</wsc:ClientContext>
</wsc:AutHeader>
</soapenv:Header>
<soapenv:Body>
<urn:customerReadRequest>
<urn:readQualification>
<urn1:internationalCustomerKey>
<urn2:internationalCustomerNumber>" + customerNumber + #"</urn2:internationalCustomerNumber>
</urn1:internationalCustomerKey>
</urn:readQualification>
</urn:customerReadRequest>
</soapenv:Body>
</soapenv:Envelope>";
}
return _xmlSOAP;
}
private void cmdCustomerRead_Click(object sender, EventArgs e)
{
lblStatus.Text = "Status:";
//ValidateCustomerCoreWSGen2(tbCustomerNumber.Text.Trim());
CallValidateCustomerAsync(tbCustomerNumber.Text.Trim());
}
private async void CallValidateCustomerAsync(string customerNumber)
{
string result = await ValidateCustomerCoreWSGen2(customerNumber);
lblStatus.Text = "Status: " + result;
}
Console
static async Task ExampleRequest()
{
var timeout = 30;
try
{
using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(timeout) })
{
int textidx = 2;
// URL to soap service
var endpointUrlCustomer = "https://REMOVED";
// Create HTTP request.
var customerBuilder = new UriBuilder(new Uri($"{endpointUrlCustomer}"));
var customerRequest = new HttpRequestMessage(HttpMethod.Post, customerBuilder.Uri);
// set SOAP action
customerRequest.Headers.Add("SOAPAction", "");
// set SOAP body content
Console.WriteLine();
Console.WriteLine("************************* CUSTOMER ***********************");
string xmlSOAP = GetXmlSOAP("CUSTOMER", textidx);
customerRequest.Content = new StringContent(xmlSOAP, Encoding.UTF8, "text/xml");
// Add signature headers to request object
await SignHttpRequestMessage(customerRequest, textidx);
Console.WriteLine("Signed request HTTP");
Console.WriteLine("-----------------------------------------");
Console.WriteLine(customerRequest + Environment.NewLine);
Console.WriteLine("Signed request XML");
Console.WriteLine("-----------------------------------------");
Console.WriteLine(customerRequest.Content.ReadAsStringAsync().Result + Environment.NewLine);
// Perform request
Console.WriteLine("Send request");
Console.WriteLine("-----------------------------------------");
var customerResponse = await client.SendAsync(customerRequest);
Console.WriteLine();
Console.WriteLine("Response HTTP");
Console.WriteLine("-----------------------------------------");
Console.WriteLine(customerResponse + Environment.NewLine);
Console.WriteLine("Response result XML");
Console.WriteLine("-----------------------------------------");
Console.WriteLine(customerResponse.Content.ReadAsStringAsync().Result + Environment.NewLine);
if (customerResponse.IsSuccessStatusCode)
{
// Do what you want with response body
var responseBody = await customerResponse.Content.ReadAsStringAsync();
}
else
{
var responseBody = await customerResponse.Content.ReadAsStringAsync();
var message = $"Response returned with status {customerResponse.StatusCode}. Reason: {customerResponse.ReasonPhrase}";
throw new Exception(message);
}
}
}
catch (HttpRequestException e)
{
throw e;
}
}
static async Task SignHttpRequestMessage(HttpRequestMessage request, int testIdx)
{
// externalize configuration of these
string certPath = "";
string keyStorePassword = "";
string keyId = "";
if (testIdx == 1)
{
keyStorePassword = "REMOVED";
keyId = "REMOVED";
}
if (testIdx == 2)
{
certPath = Path.GetFullPath(#"c:\cert2\cert.pfx"); // path to keystorefile
keyStorePassword = "REMOVED";
keyId = "REMOVED";
}
else if (testIdx == 3)
{
certPath = Path.GetFullPath(#"REMOVED"); // path to keystorefile
keyStorePassword = "REMOVED";
keyId = "REMOVED";
}
X509Certificate2Collection certs = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(certPath, keyStorePassword, X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.Exportable);
var services = new ServiceCollection()
.AddHttpMessageSigning()
.UseKeyId(keyId)
.UseSignatureAlgorithm(SignatureAlgorithm.CreateForSigning(cert, HashAlgorithmName.SHA256))
.UseDigestAlgorithm(HashAlgorithmName.SHA256)
.UseUseDeprecatedAlgorithmParameter()
.UseNonce(false)
.UseHeaders()
.Services;
using (var serviceProvider = services.BuildServiceProvider())
{
using (var signerFactory = serviceProvider.GetRequiredService<IRequestSignerFactory>())
{
var requestSigner = signerFactory.CreateFor(keyId);
await requestSigner.Sign(request);
}
}
request.Headers.Add("Signature", request.Headers.Authorization.ToString());
request.Headers.Authorization = null;
}
static string GetXmlSOAP(string operation, int testIdx)
{
string xmlSOAP = "";
if (operation == "CUSTOMER")
{
if (testIdx == 1)
{
REMOVED
}
if (testIdx == 2)
{
xmlSOAP = #"<?xml version=""1.0"" encoding=""utf-8""?>
<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:wsc=""http://REMOVED""
xmlns:urn=""urn:REMOVED""
xmlns:urn1=""urn:REMOVED""
xmlns:urn2=""urn:REMOVED"">
<soapenv:Header>
<wsc:AutHeader>
<wsc:SourceApplication>REMOVED</wsc:SourceApplication>
<wsc:DestinationApplication>REMOVED</wsc:DestinationApplication>
<wsc:Function>REMOVED</wsc:Function>
<wsc:Version>REMOVED</wsc:Version>
<wsc:ClientContext>
<wsc:userid>REMOVED</wsc:userid>
<wsc:credentials/>
<wsc:channel>REMOVED</wsc:channel>
<wsc:orgid>REMOVED</wsc:orgid>
<wsc:orgunit>REMOVED</wsc:orgunit>
<wsc:customerid>REMOVED</wsc:customerid>
<wsc:locale>no_NO</wsc:locale>
<wsc:ip>127.0.0.1</wsc:ip>
</wsc:ClientContext>
</wsc:AutHeader>
</soapenv:Header>
<soapenv:Body>
<urn:customerReadRequest>
<urn:readQualification>
<urn1:internationalCustomerKey>
<urn2:internationalCustomerNumber>REMOVED</urn2:internationalCustomerNumber>
</urn1:internationalCustomerKey>
</urn:readQualification>
</urn:customerReadRequest>
</soapenv:Body>
</soapenv:Envelope>";
}
if (testIdx == 3)
{
REMOVED
}
}
}
Windows service
internal class CustomerServices
{
private static bool _extendedLogging = true;
public static string ValidateCustomer(string customerNumber)
{
string _status = "";
string _servicesType = CommonMethods.GetAppSetting("ServicesType");
//TODO: Check format, ref. "UNSUPPORTED_FORMAT" in HandleValidateCustomerException
//TODO: Check existing, ref. "CUSTOMER_NOT_FOUND" in HandleValidateCustomerException
if (_servicesType == "COREWSGEN2")
{
_status = ValidateCustomerCoreWSGen2(customerNumber).GetAwaiter().GetResult();
}
return _status;
}
private static async Task<string> ValidateCustomerCoreWSGen2(string customerNumber)
{
string _status = "";
string _username = "";
string _orgId = "";
string _orgUnit = "";
string _channel = "";
string _sourceApplication = "";
string _destinationApplication = "";
string _function = "";
string _version = "";
int _timeout = 30;
string _endpoint = "";
string _values = "";
try
{
_extendedLogging = (CommonMethods.GetAppSetting("ExtendedLogging").ToUpper() == "TRUE" ? true : false);
_values += "ExtendedLogging" + Environment.NewLine;
_username = CommonMethods.GetAppSetting("Username");
_values += "Username" + Environment.NewLine;
_orgId = CommonMethods.GetAppSetting("OrgId");
_values += "OrgId" + Environment.NewLine;
_orgUnit = CommonMethods.GetAppSetting("OrgUnit");
_values += "OrgUnit" + Environment.NewLine;
_channel = CommonMethods.GetAppSetting("CoreWSGen2Channel");
_values += "CoreWSGen2Channel" + Environment.NewLine;
_sourceApplication = CommonMethods.GetAppSetting("CoreWSGen2SourceApplication");
_values += "CoreWSGen2SourceApplication" + Environment.NewLine;
_destinationApplication = CommonMethods.GetAppSetting("CoreWSGen2DestinationApplication");
_values += "CoreWSGen2DestinationApplication" + Environment.NewLine;
_function = CommonMethods.GetAppSetting("CoreWSGen2Function");
_values += "CoreWSGen2Function" + Environment.NewLine;
_version = CommonMethods.GetAppSetting("CoreWSGen2Version");
_values += "CoreWSGen2Version" + Environment.NewLine;
_timeout = Int32.Parse(CommonMethods.GetAppSetting("CoreWSGen2TimeoutSeconds"));
_values += "CoreWSGen2Version" + Environment.NewLine;
_endpoint = CommonMethods.GetAppSetting("CustomerServicesEndpointAddress");
if (_extendedLogging)
{
Logging.LogAction("Application settings used for customer read:" + Environment.NewLine
+ "-------------------------------------------------" + Environment.NewLine
+ "Username = " + _username + Environment.NewLine
+ "OrgId = " + _orgId + Environment.NewLine
+ "OrgUnit = " + _orgUnit + Environment.NewLine
+ "Channel = " + _channel + Environment.NewLine
+ "SourceApplication = " + _sourceApplication + Environment.NewLine
+ "DestinationApplication = " + _destinationApplication + Environment.NewLine
+ "Function = " + _function + Environment.NewLine
+ "Version = " + _version + Environment.NewLine
+ "Timeout (seconds) = " + _timeout + Environment.NewLine
+ Environment.NewLine
+ "Endpoint = " + _endpoint + Environment.NewLine);
}
}
catch (Exception _ex)
{
_status = "CONFIG_ERROR";
Logging.LogException(new Exception("CustomerServices - Error when reading configuration file. Successfully read values: " + Environment.NewLine + _values + Environment.NewLine, _ex.InnerException));
}
try
{
using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(_timeout) })
{
// Create HTTP request.
var customerBuilder = new UriBuilder(new Uri($"{_endpoint}"));
var customerRequest = new HttpRequestMessage(HttpMethod.Post, customerBuilder.Uri);
// Set SOAP action
customerRequest.Headers.Add("SOAPAction", "");
// SOAP body content
string xmlSOAP = GetXmlSOAP("CUSTOMERREAD", _sourceApplication, _destinationApplication, _function, _version, _username, _channel, _orgId, _orgUnit, customerNumber);
customerRequest.Content = new StringContent(xmlSOAP, Encoding.UTF8, "text/xml");
// Add signature headers to request object
await SignHttpRequestMessage(customerRequest);
// Call service
var customerResponse = await client.SendAsync(customerRequest);
if (_extendedLogging)
{
Logging.LogAction("Response header:" + Environment.NewLine + customerResponse + Environment.NewLine);
Logging.LogAction("Response content:" + Environment.NewLine + customerResponse.Content.ReadAsStringAsync().Result + Environment.NewLine);
}
//Response handling
if (customerResponse.IsSuccessStatusCode)
{
// Do what you want with response body
var responseBody = await customerResponse.Content.ReadAsStringAsync();
// Log response content if extended logging
if (_extendedLogging)
{
Logging.LogAction(responseBody);
}
_status = "CUSTOMER_EXISTS";
}
else
{
_status = "CUSTOMER_READ_EXCEPTION";
var responseBody = await customerResponse.Content.ReadAsStringAsync();
var message = $"Response returned with status {customerResponse.StatusCode}. Reason: {customerResponse.ReasonPhrase}";
Logging.LogException(new Exception(message));
}
}
}
catch (Exception _ex)
{
_status = "SERVICE_ERROR";
Logging.LogException(_ex);
}
return _status;
}
static async Task SignHttpRequestMessage(HttpRequestMessage request)
{
// externalize configuration of these
string certPath = "";
string keyStorePassword = "";
string keyId = "";
certPath = Path.GetFullPath(#"c:\cert2\cert.pfx"); // path to keystorefile
keyStorePassword = "internal-sls-test";
keyId = "73ae28ed2f31";
X509Certificate2Collection certs = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(certPath, keyStorePassword, X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.Exportable);
var services = new ServiceCollection()
.AddHttpMessageSigning()
.UseKeyId(keyId)
.UseSignatureAlgorithm(SignatureAlgorithm.CreateForSigning(cert, HashAlgorithmName.SHA256))
.UseDigestAlgorithm(HashAlgorithmName.SHA256)
.UseUseDeprecatedAlgorithmParameter()
.UseNonce(false)
.UseHeaders()
.Services;
using (var serviceProvider = services.BuildServiceProvider())
{
using (var signerFactory = serviceProvider.GetRequiredService<IRequestSignerFactory>())
{
var requestSigner = signerFactory.CreateFor(keyId);
await requestSigner.Sign(request);
}
}
request.Headers.Add("Signature", request.Headers.Authorization.ToString());
request.Headers.Authorization = null;
if (_extendedLogging)
{
Logging.LogAction("Signed request header:" + Environment.NewLine + request + Environment.NewLine);
Logging.LogAction("Signed request content:" + Environment.NewLine + request.Content.ReadAsStringAsync().Result + Environment.NewLine);
}
}
private static string GetXmlSOAP(string method, string sourceApplication, string destinationApplication, string function, string version, string username, string channel, string orgId, string orgUnit, string customerNumber)
{
string _xmlSOAP = "";
if (method.ToUpper() == "CUSTOMERREAD")
{
_xmlSOAP = #"<?xml version=""1.0"" encoding=""utf-8""?>
<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:wsc=""http://edb.com/ws/WSCommon_v22""
xmlns:urn=""urn:srv.cus.corews.enterprise.fs.evry.com:ws:customer:v20_1""
xmlns:urn1=""urn:srv.cus.corews.enterprise.fs.evry.com:domain:customer:v20_1""
xmlns:urn2=""urn:corews.enterprise.fs.evry.com:domain:common:v8"">
<soapenv:Header>
<wsc:AutHeader>
<wsc:SourceApplication>" + sourceApplication + #"</wsc:SourceApplication>
<wsc:DestinationApplication>" + destinationApplication + #"</wsc:DestinationApplication>
<wsc:Function>" + function + #"</wsc:Function>
<wsc:Version>" + version + #"</wsc:Version>
<wsc:ClientContext>
<wsc:userid>" + username + #"</wsc:userid>
<wsc:credentials/>
<wsc:channel>" + channel + #"</wsc:channel>
<wsc:orgid>" + orgId + #"</wsc:orgid>
<!--Optional:-->
<wsc:orgunit>" + orgUnit + #"</wsc:orgunit>
<!--Optional:-->
<wsc:customerid>" + customerNumber + #"</wsc:customerid>
<!--Optional:-->
<wsc:locale>no_NO</wsc:locale>
<wsc:ip>127.0.0.1</wsc:ip>
</wsc:ClientContext>
</wsc:AutHeader>
</soapenv:Header>
<soapenv:Body>
<urn:customerReadRequest>
<urn:readQualification>
<urn1:internationalCustomerKey>
<urn2:internationalCustomerNumber>" + customerNumber + #"</urn2:internationalCustomerNumber>
</urn1:internationalCustomerKey>
</urn:readQualification>
</urn:customerReadRequest>
</soapenv:Body>
</soapenv:Envelope>";
}
return _xmlSOAP;
}
}

Related

I have created container successfully but failed to upload an image/pdf to my blob container using Rest API

I am using PUT Blob Rest API for uploading img/pdf- PUT Blob reference. But it is showing- Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature error (403 response code).
Below are the string to sign:
"PUT\n\n\n41676\n\nimage/png\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Wed, 17 Feb 2021 10:24:02 GMT\nx-ms-version:2020-02-10\n/acc_name/container_name/12362_50800_13_s_1.png"
Below are the header details:
{ "x-ms-blob-type" : "BlockBlob" , "x-ms-date" : "Wed, 17 Feb 2021 10:24:02 GMT" , "x-ms-version" : "2020-02-10" , "Authorization" : "SharedKey acc_name:XXXQsR728D7aqyJzFi/HXk+qT9rpjYbplUG9KXXXX" , "Content-Type" : "image/png" , "Content-Length" : "41676"}
Below are the URL details:
https://acc_name.blob.core.windows.net/container_name/12362_50800_13_s_1.png
private BasicDBObject createAzureBlob(String storageAPIVersion, String storageAccURL, String storageAccName, String storageAcckey, String storageAccConString,
String containerName, BasicDBObject clientReqObj, File outputfile) throws Exception
{
log.info("Entry createAzureBlob in the GenericServicesDeligator");
BasicDBObject clientResponse = null;
String date = clientReqObj.remove(Constants.F_CREATED_DATE).toString();
String filePath = clientReqObj.remove(Constants.F_PATH).toString();
String contentLength = clientReqObj.remove("Content-Length").toString();
String contentType = clientReqObj.remove("Content-Type").toString();
String hostMethod = "PUT";
StringBuilder authorization = new StringBuilder("SharedKey ").append(storageAccName).append(":").append("sharedKeySign");
StringBuilder canonicalizedResource = new StringBuilder("/").append(storageAccName).append("/").append(containerName).append("/").append(filePath);
BasicDBObject clientReqHeader = new BasicDBObject();
// Host URL
String hostName = clientReqHeader.size()>0l?new StringBuilder("/").append(filePath).append(prepareHostInfo(clientReqHeader)).toString():new StringBuilder("/").
append(filePath).toString();
String hostURL = new StringBuilder(storageAccURL).append("/").append(containerName).append(hostName).toString().trim();
// canonicalizedResource should always be in alphabetical order
canonicalizedResource.append(prepareCanonicalizedResource(clientReqHeader));
//canonicalizedHeader should always be in alphabetical order and include only that begin with x-ms-
clientReqHeader.clear();
clientReqHeader.put("x-ms-blob-type", "BlockBlob");
clientReqHeader.put("x-ms-date", date);
clientReqHeader.put("x-ms-version", storageAPIVersion);
String canonicalizedHeader = prepareCanonicalizedHeader(clientReqHeader);
// string to sign
String stringToSign = prepareStringToSign(hostMethod, contentLength, contentType, canonicalizedHeader, canonicalizedResource.toString());
// encode the string by using the HMAC-SHA256 algorithm over the UTF-8-encoded signature string
String signature = encodeSharedKeySignature(stringToSign, storageAcckey);
clientReqHeader.put("Authorization", authorization.toString().replace("sharedKeySign", signature));
clientReqHeader.put("Content-Length", contentLength);
clientReqHeader.put("Content-Type", contentType);
clientResponse = sendAzureClientRequest(hostMethod, hostURL, clientReqHeader, clientReqObj, outputfile);
log.info("Exit createAzureBlob in the GenericServicesDeligator");
return clientResponse;
}
private String prepareHostInfo(BasicDBObject hostNameObject) throws Exception
{
StringBuilder hostName = new StringBuilder();
for(String key: hostNameObject.keySet())
{
if(hostName.length() == 0l)
hostName.append("?").append(key).append("=").append(hostNameObject.get(key));
else
hostName.append("&").append(key).append("=").append(hostNameObject.get(key));
}
return hostName.toString().trim();
}
private String prepareCanonicalizedResource(BasicDBObject hostNameObject) throws Exception
{
StringBuilder canonicalizedResource = new StringBuilder();
Map<String, String> canonicalizedMap = new TreeMap<String, String>();
canonicalizedMap.putAll(hostNameObject.toMap());
for(String key: canonicalizedMap.keySet())
{
canonicalizedResource.append("\n").append(key).append(":").append(canonicalizedMap.get(key));
}
return canonicalizedResource.toString();
}
private String prepareCanonicalizedHeader(BasicDBObject hostNameObject) throws Exception
{
StringBuilder canonicalizedHeader = new StringBuilder();
Map<String, String> canonicalizedMap = new TreeMap<String, String>();
canonicalizedMap.putAll(hostNameObject.toMap());
for(String key: canonicalizedMap.keySet())
{
canonicalizedHeader.append(key).append(":").append(canonicalizedMap.get(key).toString().trim()).append("\n");
}
return canonicalizedHeader.toString();
}
private String prepareStringToSign(String hostMethod, String contentLength, String contentType, String canonicalizedHeader, String canonicalizedResource)
{
String input = "";
input = new StringBuilder(hostMethod).append("\n").
append("\n"). // Content-Encoding + "\n" +
append("\n"). // Content-Language + "\n" +
append(contentLength!=null?contentLength:"").append("\n").
append("\n"). // Content-MD5 + "\n" +
append(contentType!=null?contentType:"").append("\n").
append("\n"). // Date
append("\n"). // If-Modified-Since + "\n" +
append("\n"). // If-Match + "\n" +
append("\n"). // If-None-Match + "\n" +
append("\n"). // If-Unmodified-Since + "\n" +
append("\n"). // Range + "\n" +
append(canonicalizedHeader).
append(canonicalizedResource).toString().trim();
return input;
}
public String getUTCDate(Date date) throws Exception
{
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
return (sdf.format(date) + " GMT").trim();
}
public static String getFileContentType(String fileType)
{
String contentType = "";
switch (fileType)
{
case "pdf":
contentType = "application/pdf";
break;
case "txt":
contentType = "text/plain";
break;
case "bmp":
contentType = "image/bmp";
break;
case "gif":
contentType = "image/gif";
break;
case "png":
contentType = "image/png";
break;
case "jpg":
contentType = "image/jpeg";
break;
case "jpeg":
contentType = "image/jpeg";
break;
case "xls":
contentType = "application/vnd.ms-excel";
break;
case "xlsx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case "csv":
contentType = "text/csv";
break;
case "html":
contentType = "text/html";
break;
case "xml":
contentType = "text/xml";
break;
case "zip":
contentType = "application/zip";
break;
default:
contentType = "application/octet-stream";
break;
}
return contentType.trim();
}
private String encodeSharedKeySignature(String inputVal, String storageAcckey) throws Exception
{
SecretKeySpec secretkey = new SecretKeySpec(new BASE64Decoder().decodeBuffer(storageAcckey), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretkey);
String hash = Base64.encodeAsString(mac.doFinal(inputVal.getBytes("UTF-8")));
return hash.trim();
}
Kindly share the solution so i would upload a image/pdf.
Thanks in advance
In the private BasicDBObject createAzureBlob() method, in the following section:
//encode the string by using the HMAC-SHA256 algorithm over the UTF-8-encoded signature string
String signature = encodeSharedKeySignature(stringToSign, storageAcckey);
clientReqHeader.put("Authorization", authorization.toString().replace("sharedKeySign", storageAcckey));
clientReqHeader.put("Content-Length", contentLength);
clientReqHeader.put("Content-Type", contentType);
You should use the signature instead of storageAcckey for Authorization header, so please change this line of code
clientReqHeader.put("Authorization", authorization.toString().replace("sharedKeySign", storageAcckey));
to
clientReqHeader.put("Authorization", authorization.toString().replace("sharedKeySign", signature));

How to wait for request to finish in Jmeter

I am currently new to Jmeter, and trying to create a Jmeter script to test how long a request takes to process and complete.
a) Authenticate using Token - Complete
b) Post Request - Complete - Returns 200
c) Get Request - Partially Completed
C: I am Trying to get be able to monitor this request to find out when its either completed failed etc.
I have created the Http Request Sample with a Get Request
I am able to get the Request 200 but it doesn't wait for completion
So running this in a console app, it waits for a certain time checking for status....
Is there a way to possibly write a code similar to the C# code in bean shell or groovy to wait. I was reading about while controller as well...
var result = WaitForBuildToComplete(dest, requestData, token, timeout);
static string GetStatus(string path, Token token)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(path);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
AddToken(token, httpWebRequest);
WebResponse response = httpWebRequest.GetResponse();
string responseFromServer = "";
using (Stream dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
}
// Close the response.
response.Close();
return responseFromServer;
}
static int WaitForBuildToComplete(string dest, RequestData requestData, Token token, int
timeout)
{
if (timeout <= 0) return 0;
var path = $"{ConfigurationManager.AppSettings[dest]}/policy?id={requestData.id}";
var startTime = DateTime.Now;
do
{
var status = GetStatus(path, token);
var msg = JsonConvert.DeserializeObject<string>(status);
var requestStatus = JsonConvert.DeserializeObject<RequestStatus>(msg);
if (!string.IsNullOrEmpty(requestStatus.DllUrl))
{
Console.WriteLine($"\nResult dll at: {requestStatus.DllUrl}");
return 0;
}
if (requestStatus.Status.ToUpper() == "FAILED")
{
Console.WriteLine($"\nFAILED");
Console.WriteLine(requestStatus.Message);
return -1;
}
if (requestStatus.Status.ToUpper() == "FAILED_DATA_ERROR")
{
Console.WriteLine($"\nFAILED_DATA_ERROR");
Console.WriteLine(requestStatus.Message);
return -1;
}
if (requestStatus.Status.ToUpper() == "NOT_NEEDED")
{
Console.WriteLine($"\nNOT_NEEDED");
Console.WriteLine(requestStatus.Message);
return -1;
}
Console.Write(".");
System.Threading.Thread.Sleep(1000);
} while ((DateTime.Now - startTime).TotalSeconds < timeout);
Console.WriteLine("Time out waiting for dll.");
return -1;
}
I started by looking at JSR223 Sampler but wanted to see if there is a better and easier way to accomplish this.
List<String> sendRequest(String url, String method, Map<String,Object> body) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(2000)
.setSocketTimeout(3000)
.build();
StringEntity entity = new StringEntity(new Gson().toJson(body), "UTF-8");
HttpUriRequest request = RequestBuilder.create(method)
.setConfig(requestConfig)
.setUri(url)
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8")
.setEntity(entity)
.build();
String req = "REQUEST:" + "\n" + request.getRequestLine() + "\n" + "Headers: " +
request.getAllHeaders() + "\n" + EntityUtils.toString(entity) + "\n";
HttpClientBuilder.create().build().withCloseable {httpClient ->
httpClient.execute(request).withCloseable {response ->
String res = "RESPONSE:" + "\n" + response.getStatusLine() + "\n" + "Headers: " +
response.getAllHeaders() + "\n" +
(response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "") + "\n";
System.out.println(req + "\n" + res );
return Arrays.asList(req, res);
}
}
}
List sendGet(String url, Map<String,String> body) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(2000)
.setSocketTimeout(3000)
.build();
RequestBuilder requestBuilder = RequestBuilder.get()
.setConfig(requestConfig)
.setUri(url)
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8");
body.forEach({key, value -> requestBuilder.addParameter(key, value)});
HttpUriRequest request = requestBuilder.build();
String req = "REQUEST:" + "\n" + request.getRequestLine() + "\n" + "Headers: " +
request.getAllHeaders() + "\n";
HttpClientBuilder.create().build().withCloseable {httpClient ->
httpClient.execute(request).withCloseable {response ->
String res = "RESPONSE:" + "\n" + response.getStatusLine() + "\n" + "Headers: " +
response.getAllHeaders() + "\n" +
(response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "") + "\n";
System.out.println(req + "\n" + res );
return Arrays.asList(req, res);
}
}
}
The approach which is normally used in JMeter is placing your request under the While Controller which will be checking the Status value which in its turn can be fetched from the response using a suitable Post-Processor so the request will be retried unless the "Status" changes to some value which you expect (or times out)
If you place the whole construction under the Transaction Controller you will get the whole time for the status to change.
Example test plan outline:

Can't find way to debug Internal Server Error (500) caused by new class

I've read a lot of the postings about 500 errors because of the channel emulator, but this is not the case here. I took the standard bot template, which works just fine with the emulator, and replaced it with
ConnectorClient connector = new ConnectorClient(new
Uri(activity.ServiceUrl));
// calculate something for us to return
// int length = (activity.Text ?? string.Empty).Length;
string responseText=
***Bot_Application2.SilviaRestClass.GetRestResult(activity.Text);***
So the issue is in executing the GetRestResult method in the SilivaRestClass.
The code itself works, I'm using it in lots of other places, as it basically sets up a simple 1)get an input utterance in text, 2)send to my SILVIA AI server, and 3)get an utterance back routine. I have a feeling it has something to do with either private vs public methods, and/or [Serializable], based on what I have read so far. The code (minus the credentials) is below. Many thanks, in advance, for any suggestions to try.
`
bool exit = false;
restResponse = "Hello";
bool sessionNew = true;
string viewMessage = null;
string SILVIAUri = "";
string SILVIACore = "/Core/Create/unique/silName";
string SILVIASubmit = "/IO/SetInputManaged/unique/hello";
string SILVIARead = "/IO/GetAll/unique";
string SILVIARelease = "/Core/Release/{unique}";
string SILVIASubKey = "";
string silName = "";
string returnMessage = null;
string holdit = null;
string holdit2 = null;
int forHold = 0;
string responseFromServer = null;
string isfalse = "false";
string myURI = null;
string unique = null;
//CREATE CORE from SILVIA SERVER
myURI = SILVIAUri + SILVIACore;
myURI = myURI.Replace("silName", silName);
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest request = WebRequest.Create(myURI);
request.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
if (sessionNew)
{
Random rnd1 = new Random();
unique = rnd1.Next().ToString() + "askgracie";
sessionNew = false;
WebResponse wResponse = request.GetResponse();
Stream dataStream = wResponse.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
// Clean up the streams and the response.
reader.Close();
wResponse.Close();
}
//SEND UTTERANCE to SILVIA
holdit = null;
myURI = null;
myURI = SILVIAUri + SILVIASubmit;
holdit = restResponse;
// holdit = HttpUtility.UrlEncode(holdit);
myURI = myURI.Replace("hello", holdit);
myURI = myURI.Replace("unique", unique);
if (holdit == "exit")
{
exit = true;
myURI = SILVIAUri + SILVIARelease;
}
System.Net.WebRequest sendRequest = WebRequest.Create(myURI);
sendRequest.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
WebResponse sendResponse = sendRequest.GetResponse();
Stream sendStream = sendResponse.GetResponseStream();
StreamReader sendReader = new StreamReader(sendStream);
string send_ResponseFromServer = sendReader.ReadToEnd();
// Clean up the streams and the response.
sendReader.Close();
sendResponse.Close();
holdit = send_ResponseFromServer;
forHold = holdit.IndexOf("success");
holdit2 = holdit.Substring(forHold + 9, 5);
if (holdit2 == isfalse)
{
var simpleUtterResponse = "The bot failed to send the
utterance to SILVIA";
}
//GETRESPONSES FROM SILVIA
returnMessage = null;
holdit = null;
responseFromServer = null;
myURI = SILVIAUri + SILVIARead;
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest readRequest = WebRequest.Create(myURI);
readRequest.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
WebResponse readResponse = readRequest.GetResponse();
Stream readStream = readResponse.GetResponseStream();
StreamReader readReader = new StreamReader(readStream);
string read_ResponseFromServer = readReader.ReadToEnd();
viewMessage = read_ResponseFromServer;
string lastRead = "ID ";
List<string> myArray = new List<string>(viewMessage.Split(new
string[] { "\r\n" }, StringSplitOptions.None));
foreach (string s in myArray)
{
if (lastRead == "type: voice")
{
returnMessage = returnMessage + " " + s.Substring(8);
}
if (s.Length < 11)
{ lastRead = s;
}
else
{ lastRead = s.Substring(0, 11);
}
if (s.Length < 11)
{ lastRead = s;
}
else
{ lastRead = s.Substring(0, 11);
}
}
// Clean up the streams and the response.
//readReader.Close();
//readResponse.Close();
if (exit)
{
myURI = SILVIAUri + SILVIARelease;
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest closeRequest =
WebRequest.Create(myURI);
closeRequest.Headers["Ocp-Apim-Subscription-Key"] =
SILVIASubKey;
WebResponse closeResponse = closeRequest.GetResponse();
}
return returnMessage;
}
}
}`
I ended up resolving this by cut/paste the class inside the same namespace and physical .cs file. – Brian Garr just now edit

Async and Await didn't work on web api

I am trying to use await on my async method but it didn't work. I input 2 array of parameters when calling the post method, only the last one is inserted
to database(I use Elasticsearch as database so when the _id is the same the document will replaced by the new one). and I found out when insert is not done yet the program is already run to query the database and the result is 0 so it's insert again instead of update.
I already add await on my program but it didn't work out. Can anyone help me with this problem? Thanks
here is my code
// POST api/values
[HttpPost]
public async Task<AvatarModel.AvatarResponse> Post(MultiLanguageTemp[] LangTemp)
{
//process param to multilanguage model
AvatarModel.AvatarResponse Resp = new AvatarModel.AvatarResponse();
try
{
for (int i = 0; i < LangTemp.Length; i++)
{
string Type = LangTemp[i].Type;
if ("ErrorCode".Equals(Type))
{
}
else
{
string GetLabelId = LangTemp[i].LabelId;
string GetTranslation = LangTemp[i].Translation;
MultiLanguage Lang = new MultiLanguage();
Lang.Type = LangTemp[i].Type;
Lang.Site = LangTemp[i].Site;
Lang.Language = LangTemp[i].LangId;
Lang.Source = LangTemp[i].Source;
Lang.TranslationList = new Dictionary<string, string>();
Lang.TranslationList.Clear();
Lang.TranslationList.Add(GetLabelId, GetTranslation);
//search elasticsearch first using id TYPE+SITE+LANG_ID+SOURCE
string ESResponse = await GetMultiLangAsync(Lang);
JObject GetResp = JObject.Parse(ESResponse);
//get elasticsearch Hits count
JToken GetHitsTotal = GetResp.SelectToken("hits.total");
int Hits = int.Parse(GetHitsTotal.ToString());
// if id exist then do update else do insert
if (Hits > 0)
{
string ResponseUpdate = await UpdateMultiLangAsync(GetLabelId, GetTranslation,Lang);
if (!ResponseUpdate.ToString().ToUpper().Contains("ERROR"))
{
Resp.Result = "0000000";
Resp.Message = "Update MultiLanguage Info is Success";
}
else
{
Resp.Result = "9000003";
Resp.Message = "Update MultiLanguage Info into ES failed";
}
}
else
{
//tasks.Add(InsertMultiLangAsync(Lang));
//insert new document into elasticsearch
string InsertESResponse = await InsertMultiLangAsync(Lang);
if (!InsertESResponse.ToUpper().Contains("ERROR"))
{
Resp.Result = "0000000";
Resp.Message = "Insert MultiLanguage Info is Success";
}
else
{
Resp.Result = "9000003";
Resp.Message = "Insert MultiLanguage Info into ES failed";
}
}
}
}
}
catch (Exception E)
{
Resp.Result = "9000005";
Resp.Message = E.Message.ToString();
}
return Resp;
}
public async Task<string> GetMultiLangAsync(MultiLanguage Lang)
{
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var Query = "{\"query\": {\"match\": {\"_id\":\"" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "\"}}}";
var StringContent = new StringContent(Query, Encoding.UTF8, "application/json");
var Response = Client.PostAsync("_search", StringContent).Result.Content.ReadAsStringAsync();
//JObject GetResp = JObject.Parse(Response.Result);
return await Response;
}
public async Task<string> InsertMultiLangAsync(MultiLanguage Lang)
{
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var JsonTextMultiLang = JsonConvert.SerializeObject(Lang, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringContent = new StringContent(JsonTextMultiLang, Encoding.UTF8, "application/json");
var ResponseInsert = Client.PostAsync("MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source, StringContent).Result.Content.ReadAsStringAsync();
return await ResponseInsert;
}
public async Task<string> UpdateMultiLangAsync(string GetLabelId,string GetTranslation, MultiLanguage Lang)
{
var UpdateES = "{\"doc\":{\"TranslationList\":{\"" + GetLabelId + "\":\"" + GetTranslation + "\"}},\"detect_noop\":true}";
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var StringContent = new StringContent(UpdateES, Encoding.UTF8, "application/json");
var ResponseUpdate = Client.PostAsync("_update", StringContent).Result.Content.ReadAsStringAsync();
return await ResponseUpdate;
}
Here is my insight.
Based on the details you provided, you have a long-running task that would eventually create/update a record in your database. Now, the problem you encounter is the second http request you send is not waiting for the first one to finish even though you are using async/await pattern. Well, this is not how it works. Regardless of what you do, whether you block the thread or not, there is thread pooling and distinct http calls will have their own thread. So using async/await would not affect that at all. For the most part, you're using async/await correctly. However, what you're trying to achieve is not done by async/await. You might want to try a messaging system to queue all the requests. In that case, you can't put clients on hold, You'd generate a request id and send it to them immediately and process the request asynchronously in time.

AD with LDAP connection error

Im trying to use a .net application but the application cant find the server in my local network.
Im using LdapExploreTool 2 with the following settings:
the base DN is "DC=exago,DC=local", the Ip address "192.168.1.250" and the server name "exago.local"
The connection is successful and this is the result:
Inputing the values:
Examining the code, i get the exception when "Bind to the native AdsObject to force authentication":
"The specified domain either does not exist or could not be contacted."
public bool IsAuthenticated(string domain, string ldapPath, string username, string pwd, string userToValidate)
{
string domainAndUsername = domain + #"\" + username;
if (string.IsNullOrEmpty(ldapPath))
SetLdapPath(domain);
else
_path = ldapPath;
App.Services.Log.LogUtils.WriteLog(Log.LogLevel.INFO, "IsAuthenticated_DirectoryEntry:" + _path + "," + domainAndUsername + "," + pwd);
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
//check if domain is valid
int domainId = AppDomains.GetDomainIdByName(domain);
if (domainId == int.MinValue)
{
return false;
}
AppDomains d = AppDomains.GetRecord(domainId);
List<AppDomainQueries> lQueries = new List<AppDomainQueries>(AppDomainQueries.GetArray());
lQueries = lQueries.FindAll(delegate(AppDomainQueries dq) { return dq.DomainId == domainId && dq.Status == 'A'; });
string queryString = string.Empty;
try
{
// Bind to the native AdsObject to force authentication.
Object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
string ldapAndQuerie = string.Empty;
//base account search
queryString = "(SAMAccountName=" + userToValidate + ")";
if (username != userToValidate)
{
if (lQueries.Count == 1)
ldapAndQuerie = lQueries.FirstOrDefault().QueryString;
if ((ldapAndQuerie != string.Empty) && (ldapAndQuerie != "*") && (ldapAndQuerie != "(objectClass = user)"))
queryString = "(&(SAMAccountName=" + userToValidate + ")" + ldapAndQuerie + ")";
}
search.Filter = queryString;
App.Services.Log.LogUtils.WriteLog(Log.LogLevel.INFO, "LDAP=" + queryString);
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (null == result)
{
return false;
}
// Update the new path to the user in the directory
_path = result.Path;
_filterAttribute = (String)result.Properties["cn"][0];
}
catch (Exception ex)
{
App.Services.Log.LogUtils.WriteLog(Log.LogLevel.ERROR, "App.Services.Core.LdapAuthentication.IsAuthenticated() Exception - (LDAP=" + queryString + ")" + ex.Message, ex);
return false;
}
return true;
}
How can i establish a connection?
The problem was the LDAP connection string,
it seems that it missed the actual location(IP + port) in the network.
LDAP://192.168.1.250:389/DC=exago,DC=local

Resources