RabbitMQ header exchange with list - rabbitmq

I am having some issues trying to understand how an exchange of type headers works.
Only one exchange, myExchange
Three queues:
myQueue1
myQueue2
myQueue3
Bindings:
myExchange => myQueue1 (x-match: any, myHeader: [test1])
myExchange => myQueue2 (x-match: any, myHeader: [test2])
myExchange => myQueue3 (x-match: any, myHeader: [test1, test2, test3])
I am expecting the header of the message to have multiple values; any combination of test1, test2, test3 (example: test1 alone, test1 and test2, test3 and test2, etc...)
myQueue3 only receives messages if they have myHeaders:[test1, test2, test3]. I would expect myQueue3 to get messages for, e.g. test1 and test2 as well.
myQueue1 only receives messages if they have myHeaders:[test1]. I would expect myQueue1 to get messages for, e.g. test1 and [test1, test2] as well.
Is there any way to achieve such behavior? Thank you

For this, I have a trick.
Bindings:
myExchange => myQueue1 (x-match: any, test1: true)
myExchange => myQueue2 (x-match: any, test2: true)
myExchange => myQueue3 (x-match: any, test1: true, test2: true, test3: true)
myQueue1 will receive all message with header containts {test1: true}.
myQueue2 will receive all message with header containts {test2: true}.
myQueue3 will receive all message with header containts one of this {test1: true}, {test2: true} or {test3: true}.
I prefer this, because Routing Key is limited by 255 bytes, but the limit of number of elements in header is very higth.
For performance, I don't know what it's the best.

I agree with the comments, I was trying to achieve something that at the moment is not supported. I will use routing keys.

You can declare multiple bindings for the same queue.
In your case the queue 3 will have three different bindings.

Related

pubnub get history from multiple channels

I am using pubnub for chat , and using userid as channel to send messages , however when i want to retrieve conversation between two users , i need to get data from both channels, how can i do that?
I have data on both channels e.g. "userAid" and "userBid" but if i query
this.pubnub.history(
{ channel: ['userAid,'userBid'], reverse: true, count: 15 },
(status, res) => {
});```
it does not return any result , if i query with only one channel it works
The History SDK call is generally meant to fetch history from a single channel. If you need to fetch history from multiple channels, you need to use Batch History methods.
Refer to https://www.pubnub.com/docs/react-native-javascript/api-reference-storage-and-playback#batch-history for more details.
An example call might be as follows, but the link above provides a list of all the parameters that can be set. Please note that the fetchMessages method can be used to fetch history from a single channel as well.
pubnub.fetchMessages(
{
channels: ['ch1', 'ch2', 'ch3'],
start: "15343325214676133",
end: "15343325004275466",
count: 25
},
(status, response) => {
// handle response
}
);
It seems history can only get messages from one channel.
Try this:
pubnub.fetchMessages({
channels: ['ch1', 'ch2', 'ch3'],
start: '15343325214676133',
end: '15343325004275466',
count: 15,
}, (status, response) => {
// handle status, response
});
Pubnub docs on getting the history:
https://www.pubnub.com/developers/chat-resource-center/docs/reference/message-history

Is there a way to test response is contained in schema?

In Karate, I'd like to have a schema variable which is a superset of the response data so that I can test multiple requests with the same schema.
This should be specially useful for GraphQL, where the request itself defines the returned fields.
Expected schema:
{
id: '#notnull',
name: '#notnull',
description: '##string',
nonNullStringField: '#string'
...
}
Given url ...
When request ...
Then match response.data <contained in> '#(mySchema)'
Response.data:
{
id: 'someId',
name: 'some name'
}
In this case, all keys returned by the response.data should be in the schema, but any key in the schema not in the response.data should be ignored.
Is there a way to do that in Karate or some plan to add this feature going forward?
Edit: updated the example, since the only attribute being missed was a nullable one.
I'm not convinced an enhancement is needed, because the optional marker ##foo was designed for this purpose, and this already works:
* def schema = { id: '#notnull', name: '#notnull', description: '##string' }
* def response = { id: 'someId', name: 'some name' }
* match response == schema
EDIT: but since you want to limit your schema to the keys in the response in a "generic" way, you can do this:
* def expected = {}
* def fun = function(k, v){ expected.put(k, schema[k]) }
* eval karate.forEach(response, fun)
* match response == expected
You should be able to easily create a re-usable JS or Java utility that achieves the above. A few reasons I'm not in favor of adding another syntax / match keyword is that nested JSON may have some interesting edge cases that will make this complex. And I don't want to complicate match any further. As I said in the comments, IMO schema validation is the last thing you need to test for in GraphQL, it is pretty much guaranteed. This is the first time anyone has requested this in 2 years, so there's that. You could consider submitting a PR of course :)

How to use query parameter as col name on sequelize query

So, I have an Express server running Sequelize ORM. Client will answer some questions with radio button options, and the answers is passed as query parameters to the URL, so I can make a GET request to server.
The thing is: my req.query values are supposed to be the column names for my database table. I want to know if it's possible to get the response from the database using Sequelize, and passing the parameters as the column name of the table.
async indexAbrigo(req, res) {
try {
let abrigos = null
let type = req.query.type // type = 'periodoTEMPORARIO'
let reason = req.query.reason // reason = 'motivoRUA'
abrigos = await Abrigos.findAll({
attributes: ['idABRIGOS'],
where: {
//I want type and reason to be the parameters that I got from client
type: 'S',
reason: 'S'
}
})
}
res.send(abrigos)
}
This is not working, the result of the query is something like
(SELECT `idABRIGOS` FROM Abrigos WHERE `type` = `S` AND `reason` = `S`)
Instead, I need that type and reason get translated to their values, and these values will be passed to the SQL. Is it possible to do with Sequelize? Or is it even possible with any ORM for Node/Express?
Thanks.
Yes, you can do it with computed property names. It would look like this:
where: {
[type]: 'S',
[reason]: 'S'
}
Your node.js version must be compatible with ES6.
Thank you - I am passing parameters right from req.body and this worked perfectly for me so I am posting it in the event that it may save someone time.
app.post('/doFind', (req, res) => {
Abrigos.findAll(
{[req.body.field]: req.body.newVal},
{returning: true, where: {id: req.body.id}}
)
.then( () => {
res.status(200).end()
})
.catch(err => {
console.log("Err: " + err)
res.status(404).send('Error attempting to update database').end()
})
})

Duplicate console.log output of gun map when using gundb

Does this function duplicate results as a bug or am I causing this? The output always has 1 or more records duplicated. In this example, Bank of China is always listed twice in output.
gun.get('savings_accounts').map(function (name, ID) {
console.log( name.name, ID );
}, true)
My code:
localStorage.clear();
var gun = Gun();
////////////////////////////////////////////////////// create record
var acc1 = gun.put({
name: "Bank of America",
accType: "Savings",
last4: "4123",
favorite: true,
status: true,
created: "some date created"
});
var acc2 = gun.put({
name: "Bank of China",
accType: "Savings",
last4: "5123",
favorite: true,
status: true,
created: "some date created"
});
gun.get('savings_accounts').map(function (name, ID) {
console.log( name.name, ID );
}, true)
From the author of GunDB, Mark Nadal
1) gun.get('savings_accounts').map().val(cb) is what you want for normal / procedural / easy things.
HOWEVER...
2) gun is actually functional/reactive (FRP), or also known as streaming/event oriented. The data might/will get called multiple times (if you don't use .val) because A) in-memory replies, B) your browser's localStorage replies, C) the server will reply, D) server will relay to other browser peers which each might reply with data.
^ that is the "realtime" part of gun.
.val only fires once (well per item on the chain, so if you do map().val(cb) the val will get fired multiple times but only once from each item in the list).
use .val(cb) if you are doing procedural things.
Use .on(cb) (which is what .map(cb) uses internally. Most API methods internally use .on) if you want to subscribe to realtime updates of the data.
you'll slowly find that the realtime/FRP/event/streaming as being a much cleaner way to write your apps.

Logstash condition to check if message contains any of from list of string

I have a javastack trace in message field and an array field having list of string like ["NullPointer", "TimeOutException"].
I want a conditional check on message field such that it checks if message contains any of from list of string.
Any idea how to get this?
It's a bit of a hack, but check out the translate{} filter. You could define your fields to translate to "1" (true, etc), with a default of "0". Then check that value to determine if it was in the set.
EDIT: for those who don't like to fish:
filter {
translate {
field => myInputField
dictionary => [
"NullPointer", 1,
"TimeOutException", 1
]
fallback => 0
destination => myOutputField
}
if [myOutputField] == "1" {
# it contained one of the items in the dictionary
...
}
else {
# it did not contain one of the items in the dictionary
...
}
}