I don't think I would be able to discuss all of these questions at the same time. We can discuss one by one, probably starting with higher priority ones.
Fair, let's start with the part of
This would follow the AMQP logic of long term connections which contain many channels and also reduce code duplication (where every class that needs AMQP has implemented the same connection/channel establishment)?
The connection URL would be different for connections, which is the key for storing the connections (e.g. amqps://positions:positions@rabbit and amqps://events:events@rabbit), thus there would be two different connections with different usernames/passwords or hostnames be created.
E.g. Hashtable<String, Connection> activeConnections
where one would get the connection out with activeConnections.get("amqps://positions:positions@rabbit")
It's not a big problem. Just a best practice. Creating connections does consume some resources on both sides, but it's not a massive overhead. SSL a bit more, but again I won't put this into table as a major argument, just added benefit.
What is real added benefit is having a single place where connection and client are implemented. Right now if I'd implement notifications forwarding based on the same logic, I'd create a third connection with it's own connection management etc. whereas it can be actually abstracted out to a single place. The client would be right now logically in a wrong place as well, I'd rather reuse already implemented client, which is sitting right now in the forwarders
, instead of duplicating the code.
It sounds like your main motivation is some additional customization you want to do. Is that correct?
Yes, that is correct. We need to get the notification data out of the system using RabbitMQ and that functionality is missing right now. So when I implemented the code, there was duplication on client construction and lack of SSL client certs. So when implementing these parts it became clear that the whole thing can be unified and handled in single place. Question is - if and how this should merged back up, should there be any wish for that - which also drives the questions around namings and conventions.
If you want to change the way this works, we would probably need to change all other forwarders. Are you interested in taking on that work?
Not sure it has that significant change (I was very keen on ensuring that the amount of changes to existing behaviour are as minimal as possible). Currently it looks something like https://github.com/traccar/traccar/compare/master...laazik:traccar:rabbitmq-ssl-client
Main module key change is pushing in injector to the event/position forwarder so that relevant classes can be pulled in using DI (as event/position are constructed not injected). In relevant event/position forwarder main change would be fetching the connection from manager instead of creating it and avoiding exchange declaration, if needed (different type of already declared exchange will resullt in RuntimeException).
I'd personally like to add some tests there, though works in my production (not sure if better than works on my laptop).
Also please ignore the azure pipelines buildfile (would remove this) and gradle checkstyle override (used it in local dev for crlf warnings).
Though if there is an idea of how to make some things better in general for forwarders can take a look into for sure.
I don't think it's that big of a change, but I want all forwarders to have consistent implementation. I don't want to change just one to be its own thing.
Hi,
I have a need for the notifications over AMQP thus have been working on some coding and a couple of questions popped up, specifically on notifications side (before I throw in PR), so I can understand clearly the logic behind some decisions. I'm more than happy to move all this discussion into a PR debate as well, if this is better approach, though here it remains more "discoverable" in the later stage it seems...
General integration
Extracting and making the client reusable for notifications and event/position forwarding is very straightforward and reduces significantly the duplications.
AmqpConnectionManager
andAmqpClient
in thehelper
package, but as there is mail and SMS packages, would it make sense to have moved it toamqp
package perhaps?PositionForwarder
andEventForwarder
inMainModule
is fine (I personally prefer the constructors not to overflow with parameter lists)?AMQP Client SSL management
FORWARDER_AMQP_SSL_KEYSTORE
vsFORWARDER_AMQP_SSLKEYSTORE
(and similarlynotificator.amqp.ssl.keystore
vs.notificator.amqp.sslkeystore
)? Personal preference being the first one, but I'm fine with whatever the best practice is.User attributes