Akka.Streams.Amqp.IncomingMessage.Envelope.RoutingKey value is incorrect - c#

I am trying to read the incoming message on RabbitMQ via Akka.streams.Ampq source but the RoutingKey is incorrect.
Another concerning issue that the envelope does not contain the exchange name.
//code coming back with incorrect key
public void Consume(IActorRef consumerActor)
{
//Source =RabbitMQ
//Sink = Our App
var queueDeclaration = QueueDeclaration.Create(QueueName)
.WithDurable(true)
.WithAutoDelete(false);
var amqpSource = AmqpSource.AtMostOnceSource(
NamedQueueSourceSettings.Create(ConnectionSettings, QueueName).WithDeclarations(queueDeclaration),
bufferSize: 10);
var sink = Sink.ActorRef<SubMessage>(consumerActor, "complete");
var result =
amqpSource.Select(b => new SubMessage(b.Bytes.ToString(Encoding.UTF8), ConvertProperties(b.Properties), b.Envelope.RoutingKey))
.TakeWhile(x => { return true; }, true)
.RunWith(sink, Materializer);
}
//publish Method
public void Publish(dynamic message, string exchangeName)
{
var typeOf = message.GetType().Name;
var jsonMessage = Newtonsoft.Json.JsonConvert.SerializeObject(message);
//Source = Our App
//Sink = RabbitMQ
//Connections
AmqpConnectionDetails.Create(_ampqSettings.Host, _ampqSettings.Port)
.WithCredentials(AmqpCredentials.Create(_ampqSettings.UserName, _ampqSettings.Password))
.WithAutomaticRecoveryEnabled(true)
.WithNetworkRecoveryInterval(TimeSpan.FromSeconds(1));
var queueDeclaration = QueueDeclaration.Create(QueueName)
.WithDurable(true)
.WithAutoDelete(false);
var exchangeDeclaration = ExchangeDeclaration.Create(exchangeName, "direct").WithDurable(true);
var bindingDeclaration = BindingDeclaration.Create(QueueName, exchangeName).WithRoutingKey(typeOf);
//create sink
var amqpSink = AmqpSink.CreateSimple(
AmqpSinkSettings.Create(ConnectionSettings)
.WithRoutingKey(QueueName)
.WithDeclarations(exchangeDeclaration, queueDeclaration, bindingDeclaration));
//run sink
Source.From(new string[] { jsonMessage }).Select(ByteString.FromString).RunWith(amqpSink, Materializer).Wait();
}
//Extra Info below
//**********Class constructor
private readonly IAMQPSettings _ampqSettings;
private readonly Akka.Actor.ActorSystem System;
private readonly AmqpConnectionDetails ConnectionSettings;
private readonly ActorMaterializer Materializer;
private readonly string QueueName;
public EventBus(Akka.Actor.ActorSystem system, IAMQPSettings ampqSettings)
{
_ampqSettings = ampqSettings;
System = system;
ConnectionSettings = AmqpConnectionDetails.Create(ampqSettings.Host, ampqSettings.Port)
.WithCredentials(AmqpCredentials.Create(ampqSettings.UserName, ampqSettings.Password))
.WithAutomaticRecoveryEnabled(true)
.WithNetworkRecoveryInterval(TimeSpan.FromSeconds(1));
Materializer = ActorMaterializer.Create(System);
QueueName = ampqSettings.QueueName;
}
//SubMessage structure
public class SubMessage
{
public SubMessage(string message, Dictionary<string, object> properties = null, string routingKey = null, string exchangeName = null)
{
ExchangeName = exchangeName;
Message = message;
Properties = properties;
RoutingKey = routingKey;
}
public string Message { get; private set; }
public Dictionary<string, object> Properties { get; private set; }
public string RoutingKey { get; private set; }
public string ExchangeName { get; private set; }
}
Actual behaviour: I get the QueueName which is "Tax_Queue"
Expected behaviour : I am expecting to get the QueueName which is my class e.g MyTestClass RoutingKey.

I found the issue:
code says .WithRoutingKey(QueueName) instead of WithRoutingKey(routingKey)

Related

Filter sublist record/s along with parent list field

I want to filter records which have ModelLogin.LoginDate = dateTimeToday and ModelLoginRecords.LoginPurpose = "Update".
Result must be a ModelLogin list which have its LoginDate(dateTimeToday) and LoginRecords sublist which have "Update" only.
Model 1
public class ModelLogin
{
public DateTime LoginDate;
public List<ModelLoginRecords> LoginRecords;
public ModelLogin(DateTime LoginDate, List<ModelLoginRecords> LoginRecords)
{
this.LoginDate = LoginDate;
this.LoginRecords = LoginRecords;
}
}
Model 2
public class ModelLoginRecords
{
public string UserName;
public string LoginPurpose;
public ModelLoginRecords(string UserName, string LoginPurpose)
{
this.UserName = UserName;
this.LoginPurpose = LoginPurpose;
}
}
Sample data
List<ModelLogin> listLogins = new List<ModelLogin>();
List<ModelLoginRecords> loginRecordsList = new List<ModelLoginRecords>();
loginRecordsList.Add(new ModelLoginRecords("Alex", "Update"));
loginRecordsList.Add(new ModelLoginRecords("David", "Update"));
loginRecordsList.Add(new ModelLoginRecords("Jason", "Remove"));
listLogins.Add(new ModelLogin(dateTimeToday, loginRecordsList));
loginRecordsList = new List<ModelLoginRecords>();
loginRecordsList.Add(new ModelLoginRecords("Kate", "Update"));
loginRecordsList.Add(new ModelLoginRecords("William", "Remove"));
listLogins.Add(new ModelLogin(dateTimeYesterday, loginRecordsList));
Please check the code below.
public class Test
{
[Fact]
public void test()
{
//arrange
var updatePurpose = "Update";
var removePurpose = "Remove";
List<ModelLogin> listLogins = new();
var dateTimeToday = DateTime.Today;
var dateTimeYesterday = dateTimeToday.AddDays(-1);
List<ModelLoginRecords> loginRecordsList = new();
loginRecordsList.Add(new ModelLoginRecords("Alex", updatePurpose));
loginRecordsList.Add(new ModelLoginRecords("David", updatePurpose));
loginRecordsList.Add(new ModelLoginRecords("Jason", removePurpose));
listLogins.Add(new ModelLogin(dateTimeToday, loginRecordsList));
loginRecordsList = new List<ModelLoginRecords>
{
new ModelLoginRecords("Kate", updatePurpose),
new ModelLoginRecords("William", removePurpose)
};
listLogins.Add(new ModelLogin(dateTimeYesterday, loginRecordsList));
//act
var loginModelsWithUpdatePurpose = listLogins.Where(listLogin =>
listLogin.LoginDate.Date == dateTimeToday.Date &&
listLogin.LoginRecords.Any(i => i.LoginPurpose == updatePurpose)
).Select(i =>
new ModelLogin(
i.LoginDate,
i.LoginRecords.Where(j => j.LoginPurpose == updatePurpose).ToList()
)
).ToList();
//assert
foreach (var loginModel in loginModelsWithUpdatePurpose)
Assert.DoesNotContain(loginModel.LoginRecords, i => i.LoginPurpose != updatePurpose);
}
}
public class ModelLoginRecords
{
public string UserName { get; private set; }
public string LoginPurpose { get; private set; }
public ModelLoginRecords(string userName, string loginPurpose)
{
UserName = userName;
LoginPurpose = loginPurpose;
}
}
public class ModelLogin
{
public DateTime LoginDate { get; private set; }
public IEnumerable<ModelLoginRecords> LoginRecords { get; private set; }
public ModelLogin(DateTime loginDate, IEnumerable<ModelLoginRecords> loginRecords)
{
LoginDate = loginDate;
LoginRecords = loginRecords;
}
}

Singleton property not updating during "OnClicked" event

I'm sure I remember this being a threading issue, but I can't find an answer. It seems like it should be simple. I have the following code:
private void Dingle_Clicked(object sender, RoutedEventArgs e)
{
dynamic doc = ScraperBrowser.Document;
string htmlText = doc.documentElement.InnerHtml;
htmlText = htmlText.Replace("\r\n", " ");
Regex targetStart = new Regex(this works just fine);
MatchCollection target = targetStart.Matches(htmlText);
string priceData = target[0].Value;
foreach (StorePriceData spData in Lists.Singleton.MedicineList[medIndex].Prices)
{
Regex rx = new Regex(spData.StoreName + #".+?(\$\d+\.\d+)");
MatchCollection matches = rx.Matches(priceData);
if (matches.Count > 0)
{
if (matches[0].Groups.Count > 0)
{
spData.MedicinePrice = matches[0].Groups[1].Value;
}
}
}
string cookie = Application.GetCookie(new Uri("https://www.goodrx.com"));
++medIndex;
ScraperBrowser.Navigate(Lists.Singleton.MedicineList[medIndex].GoodRxUrlString);
}
The problem I'm having is that the spData.MedicinePrice takes the value, but the value in the singleton "MedicineList" is not being updated. How can I make that value update?
The singleton code:
public class Lists
{
private static Lists _singleton;
public static Lists Singleton
{
get
{
if (_singleton == null) _singleton = new Lists(); return _singleton;
}
}
public List<MedicineInfo> MedicineList {
get
{
return new List<MedicineInfo>()
{
new MedicineInfo() { Name = "ZOLPIDEM TAB 10MG", Doses = "30 tablets" },
new MedicineInfo() { Name = "PANTOPRAZOLE TAB 40MG", Doses = "30 tablets" }
};
}
}
}
MedicineInfo class code:
public class MedicineInfo
{
public MedicineInfo()
{
Prices = new List<StorePriceData>()
{
new StorePriceData() { StoreName = "xxxx" },
new StorePriceData() { StoreName = "yyyy" },
new StorePriceData() { StoreName = "zzzz" },
};
}
public string Name { get; set; }
public string Doses { get; set; }
public List<StorePriceData> Prices { get; set; }
}
Thanks!
Carl
You are returning a new List<MedicineInfo> each time the getter of MedicineList is called.
Also, Lists is not really a singleton. A better implementation would look something like this:
public sealed class Lists
{
private static readonly Lists _singleton = new Lists();
private readonly List<MedicineInfo> _medicineList = new List<MedicineInfo>
{
new MedicineInfo() { Name = "ZOLPIDEM TAB 10MG", Doses = "30 tablets" },
new MedicineInfo() { Name = "PANTOPRAZOLE TAB 40MG", Doses = "30 tablets" }
};
private Lists() { }
public static Lists Singleton => _singleton;
public List<MedicineInfo> MedicineList => _medicineList;
}

Error while reading data from azure table storage

I'm writing a code to read values from a table storage. The code is similar to printing nodes in a tree level by level.
eg:
root
Level1child1 -> Level1child2 -> Level1child3
string tablename = "<table-name">;
string storageAccountName = "<storage-account-name";
var baseurl = #$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var sastoken = getAccountSASToken();
string filter = #"&$filter=PartitionKey%20eq%20'123'%20and%20RowKey%20eq%20'abc'";
baseurl = $"{baseurl}{sastoken}{filter}";
var data = HttpHelper.GetForOData(baseurl);
var responseData = data.Data.Replace(".", "_");
var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
Queue<int> strQ = new Queue<int>();
Console.WriteLine(odata.value[0].Email);
strQ.Enqueue(odata.value[0].TreeNodeID);
while (strQ.Any())
{
var url = #$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var token = _tableStorageRepository.GetAccountSASToken();
filter = #"&$filter=ParentNodeId%20eq%20" + strQ.Peek();
url = $"{url}{token}{filter}";
data = HttpHelper.GetForOData(url);
responseData = data.Data.Replace(".", "_");
odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
foreach (var m in odata?.value)
{
Console.WriteLine(m.Email);
strQ.Enqueue(m.TreeNodeID);
}
strQ.Dequeue();
}
public class ODataResponse
{
public string odata_metadata { get; set; }
public List<ODatavalue> value { get; set; }
}
public class ODatavalue
{
public string odata_type { get; set; }
public string odata_id { get; set; }
public string odata_etag { get; set; }
public string odata_editLink { get; set; }
public string RowKey { get; set; }
public string Email { get; set; }
public int ParentNodeID { get; set; }
public int TreeNodeID { get; set; }
}
Code for HttpHelper class: https://github.com/xyz92/httphelper/blob/master/HttpHelper.cs
The first time when I ran this code, it only printed root node.
The second time when I ran this code, it printed root node and Level1child1 node.
For the next runs, it printed root node, Level1child1 node & Level1child2 node.
The last node Level1child3 node is getting printed very rarely on some runs.
What am I missing in this code?
UPDATE:
Sample responseData:
{
"odata_metadata": "https://<storage-account-name>_table_core_windows_net/$metadata#<table-name>",
"value": [{
"odata_type": "<storage-account-name>_<table-name>",
"odata_id": "https://<storage-account-name>_table_core_windows_net/<table-name>(PartitionKey='123',RowKey='abc')",
"odata_etag": "W/\"datetime'2020-09-01T16%3A34%3A21_3342187Z'\"",
"odata_editLink": "<table-name>(PartitionKey='123',RowKey='abc')",
"PartitionKey": "123",
"RowKey": "abc",
"Timestamp#odata_type": "Edm_DateTime",
"Timestamp": "2020-09-01T16:34:21_3342187Z",
"Email": "email",
"ParentNodeID": 1,
"TreeNodeID": 2
}
]
}
Table columns:
Sample data in Table:
Sample outputs while running code:
According to my test, I cannot reproduce your issue in my environment. My test is as below
Table columns:
Sample data in table
Code I use your HttpHelper class to send request
class Program
{
static async Task Main(string[] args)
{
string storageAccountName = "andyprivate" ;
string tableName = "test";
var baseurl = #$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var sastoken = "";
string filter = #"&$filter=PartitionKey%20eq%20'123'%20and%20RowKey%20eq%20'abc'";
baseurl = $"{baseurl}{sastoken}{filter}";
var data = HttpHelper.GetForOData(baseurl);
var responseData = data.Data.Replace(".", "_");
var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
Queue<int> strQ = new Queue<int>();
Console.WriteLine("----root----");
Console.WriteLine(odata.value[0].Email);
strQ.Enqueue(odata.value[0].TreeNodeID);
while (strQ.Any())
{
int i = 0;
var url = #$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var token = "";
filter = #$"&$filter=ParentNodeID eq {strQ.Peek()}";
url = $"{ url}{token}{filter}";
data = HttpHelper.GetForOData(url);
responseData = data.Data.Replace(".", "_");
odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
Console.WriteLine($"----TreeNode{strQ.Peek()}----");
foreach (var m in odata?.value)
{
if (i == 0) {
strQ.Enqueue(m.TreeNodeID);
i = 1;
}
Console.WriteLine(m.Email);
}
strQ.Dequeue();
}
Console.ReadLine();
}
}
public class ODataResponse
{
public string odata_metadata { get; set; }
public List<ODatavalue> value { get; set; }
}
public class ODatavalue
{
public string odata_type { get; set; }
public string odata_id { get; set; }
public string odata_etag { get; set; }
public string odata_editLink { get; set; }
public string RowKey { get; set; }
public string Email { get; set; }
public int ParentNodeID { get; set; }
public int TreeNodeID { get; set; }
}
Update
My test code
Rest API (I use your HttpHelper class to send request)
class Program
{
static async Task Main(string[] args)
{
string storageAccountName = "andyprivate" ;
string tableName = "test";
var baseurl = #$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var sastoken = "";
string filter = #"&$filter=PartitionKey%20eq%20'123'%20and%20RowKey%20eq%20'abc'";
baseurl = $"{baseurl}{sastoken}{filter}";
var data = HttpHelper.GetForOData(baseurl);
var responseData = data.Data.Replace(".", "_");
var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
Queue<int> strQ = new Queue<int>();
Console.WriteLine("----root----");
Console.WriteLine(odata.value[0].Email);
strQ.Enqueue(odata.value[0].TreeNodeID);
while (strQ.Any())
{
int i = 0;
var url = #$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var token = "";
filter = #$"&$filter=ParentNodeID eq {strQ.Peek()}";
url = $"{ url}{token}{filter}";
data = HttpHelper.GetForOData(url);
responseData = data.Data.Replace(".", "_");
odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
Console.WriteLine($"----TreeNode{strQ.Peek()}----");
foreach (var m in odata?.value)
{
if (i == 0) {
strQ.Enqueue(m.TreeNodeID);
i = 1;
}
Console.WriteLine(m.Email);
}
strQ.Dequeue();
}
Console.ReadLine();
}
}
public class ODataResponse
{
public string odata_metadata { get; set; }
public List<ODatavalue> value { get; set; }
}
public class ODatavalue
{
public string odata_type { get; set; }
public string odata_id { get; set; }
public string odata_etag { get; set; }
public string odata_editLink { get; set; }
public string RowKey { get; set; }
public string Email { get; set; }
public int ParentNodeID { get; set; }
public int TreeNodeID { get; set; }
}
SDK. I use the package Microsoft.Azure.Cosmos.Table
string storageAccountName = "andyprivate";
string accountKey ="";
string tableName = "test";
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(storageAccountName, accountKey), true);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient(new TableClientConfiguration());
CloudTable table = tableClient.GetTableReference(tableName);
TableOperation retrieveOperation = TableOperation.Retrieve<CustomEntity>("123", "abc");
TableResult result = await table.ExecuteAsync(retrieveOperation);
CustomEntity entity = result.Result as CustomEntity;
Queue<int> strQ = new Queue<int>();
Console.WriteLine("----root----");
Console.WriteLine(entity.Email);
strQ.Enqueue(entity.TreeNodeID);
while (strQ.Any()) {
int i = 0;
TableQuery<CustomEntity> query = new TableQuery<CustomEntity>()
.Where(
TableQuery.GenerateFilterConditionForInt("ParentNodeID", QueryComparisons.Equal,strQ.Peek())
);
Console.WriteLine($"----TreeNode{strQ.Peek()}----");
foreach (CustomEntity m in table.ExecuteQuery(query) ) {
Console.WriteLine(m.Email);
if (i == 0) {
strQ.Enqueue(m.TreeNodeID);
i = 1;
}
}
strQ.Dequeue();
}

Error "Unexpected character encountered while parsing value"

while I am trying to make a http request with httpClient I keep getting this error but I do not know why.
Unexpected character encountered while parsing value: c. Path '',
line 0, position 0."]},"title":"One or more validation errors
occurred.","status":400,
here is my code, and I am using console application to make the request:
class Program {
static void Main (string[] args) {
Data _dt = new Data();
_dt.IP = "192.156.25";
_dt.LogText = "test from http";
_dt.LogType = 1;
_dt.StoreId = 14;
_dt.StoreName = "testino";
_dt.UserId = 2;
NewAddStoreLog(_dt);
}
static void NewAddStoreLog (Data dt) {
HttpClient http = new HttpClient ();
var content = new StringContent (dt.ToString (), Encoding.UTF8, "application/json");
var result = http.PostAsync ("http://192.168.8.180:88/Logs/RecordLogs", content).Result;
string strResult = System.Text.Encoding.UTF8.GetString (result.Content.ReadAsByteArrayAsync ().Result);
System.Console.WriteLine(strResult);
}
}
public class Data {
public int StoreId { get; set; }
public int UserId { get; set; }
public string IP { get; set; }
public int LogType { get; set; } //Enum
public string LogText { get; set; }
public string StoreName { get; set; }
}

values to dictionary c# .net

public class Response
{
public User[] Users { get; set; }
}
public class User
{
public string Uid { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
public int Online { get; set; }
public int[] Lists { get; set; }
}
private void c_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
lock (this)
{
string json = e.Result;
// var response = JsonConvert.DeserializeObject(json);
var response = JObject.Parse(json);
// var COUNT = JsonConvert.DeserializeObject<List<User>>(json);
// MessageBox.Show(response.ToString());
var getcount = response["response"].Children<JObject>();
int count_friends=getcount.Cast<JToken>().Values("uid").Count();
Response rr = new Response();
for (int i = 0; i <count_friends; i++) {
//rr.Users.ToDictionary(rr.Users[i].Uid => response["response"][i]["uid"].ToString());
// rr.Users[i].First_Name = response["response"][i]["first_name"].ToString(); --DOESN'T WORKS
// Debug.WriteLine("OUT: "+(string)response["response"][i]["uid"].ToString());
//Debug.WriteLine("OUT: " + COUNT.Count());
}
Debug.WriteLine(rr.Users.ToString());
// string[] names = rr.Users.Select(d => d.First_Name).ToArray();
// string[] uids = response.Users.Select(d => d.Uid).ToArray();
// Dictionary<string,string> users = response.Users.ToDictionary(d => d.First_Name);
// Dictionary<string, string> usersById = response.Users.ToDictionary(d => d.Uid, d => d.First_Name);
}
}
I need to get acces to a dictionary like "select from Response.User all where Online==1"
But in the start how I can create a DB(linq) with classes above ?
All values stored in response["response"][i]["uid"],response["response"][i]["first_name"]...
is this what your looking for?
Dictionary<string,List<Dictionary<string,object>>>
this is vary bad design, try and rethink the problem to come up with a better solution
public struct User {
public int Uid;
public string First_Name;
public string Last_Name;
public bool isonline;
}
Than you can write values like
User[] usr= new User[count_friends];
// Response rr = new Response();
for (int i = 0; i <count_friends; i++) {
usr[i].Uid =(int) response["response"][i]["uid"];

Categories