MySQL listen notify equivalent - mysql

Is there an equivalent of PostgresQL's notify and listen in MySQL? Basically, I need to listen to triggers in my Java application server.

Ok, so what I found is that you can make UDF functions in mysql that can do anything but need to be written in C/C++. They can be then called from triggers on updates in database and notify your application when update happened. I saw that there are some security concerns. I did not use it myself but from what I can see it looks like something that could accomplish what you want to do and more.
http://dev.mysql.com/doc/refman/5.6/en/adding-udf.html

The github project mysql-notification provides a MySQL user defined function MySQLNotification() as a plugin to MySQL that will send notification events via a socket interface. This project includes a sample NodeJS test server that receives the notification events that could be adapted for Java or any other socket service.
Example use:
$ DELIMITER ##
$ CREATE TRIGGER <triggerName> AFTER INSERT ON <table>
FOR EACH ROW
BEGIN
SELECT MySQLNotification(NEW.id, 2) INTO #x;
END##
Project includes full source code and installation instructions for OSX and Linux. License is GNU v3.

No, there aren't any built-in functions like these yet.
You need to "ping" (every 1-5 seconds) database with selecting with premade flag like "read" 0/1. After
SELECT * FROM mytable WHERE read = 0
update it with read = 1

I needed to do this, so I designed my application to send the update notices itself.
E.g.
--Scenario--
User A is looking at record 1
User B saves an update to record 1 while User A has it open.
Process:
I wrote my own socket server as a Windows Service. I designed a que like system which is basically,
EntityType EntityID NoticeType
Where the EntityType is the type of Poco in my data layer that needs to send out notices, EntityID is the primary key value of the row that changed in sql (the values of the poco), and NoticeType is 1 Updated, 2 Inserted, and 3 Deleted.
The socket server accepts connections from the server side application code on a secure connection "meaning client side code cannot make requests designed to be sent by the server side application code"
The socket server accepts a message like
900 1 1023 1
Which would mean the server needs to notify concerned client connections that Entity Type 1 "Person" with ID 1023 was Updated.
The server knows what users need to be notified because when User's look at a record, they are registered in the socket server as having an interest in the record and the record's ID which is done by the web socket code in the client side javascript.
Record 1 is a POCO in my app code that has an IsNew and IsDirty field. "Using EntityFrameWork6 and MySql" If UserB's save caused an actual change (and not just saving existing data) IsDirty will be true on the postback on UserB's POCO.
The application code see's the record is dirty then notifies the socket server with a server side sent socket "which will be allowed" that says Entity 1 with ID 1023 was Updated.
The socket server sees it, and puts it in the que.
Being .Net, I have a class for concerned users that uses the same pocos from the data layer running in the Socket Server window service. I use linq to select users who are working with an entity matching the entity type and primary key id of the entity in the que.
It then loops through those users and sends them a socket like
901 1 1023 1 letting them know the entity was updated.
The javascript in the client side receives it causing users B's page to do an ajax postback on Record 1, But what happens with UserA's is different.
If user A was in the process of making a change, they will get a pop up to show them what changed, and what their new value will be if they click save and asks them which change they want to keep. If UserA doesn't have a change it does an ajax postback with a notification bar at the top that says "Record Change: Refreshed Automatically" that expires after a few seconds.
The Cons to this,
1. It's very complex
2. It won't catch insert/update/delete operations from outside of the application.
In my case, 2 won't happen and if 2 does happen it's by myself or another dev who knows how to manually create the notify que requests "building an admin page for that".

You can use https://maxwells-daemon.io to do so.
It is based on mysql bin logs, when changes in database is occurred it will send json message with updates to kafka, rabbitmq or other streaming platforms

Related

Why my Soffid JSON REST Web Services Connector does not update an object in the target system?

I am trying to connect my Soffid 3 server with our custom web application named Schrift. I am using а JSON REST Web Services Connector for this purpose. I added REST Web service plugin and then configured an agent with JSON/XML/SOAP Rest webservice type.
Loading of objects is working fine. My REST connector connects to the web service successfully and gets data of the accounts.
The problem is when I am trying to update some data (for example, I am trying to lock an account), nothing happens. And unfortunately I don't know what should be happening. When should REST connector send updated data to the managed system and in which way? I didn't find any log entries saying that REST connector was trying to update an object on managed system. Maybe I did smth wrong or missed something.
I would appreciate for any help. I can post any conf or log details if you need.
Update#1
(I did some investigation after the first answer)
I checked the agent settings: Read only and Manual account creation are set to no
The account was set to unmanaged type, but I succeeded in changing its type to shared and then to single without getting an error. Now it is set to single
The task queue is empty.
Also I've checked that update method is present and update properties are set correctly. updateParams is not set (it means that all attributes should be sent to the managed system).
But when I change status of the account (from Enable to Disable), nothing happens.
In the console log I can see only these lines
14-Sep-2021 13:26:29.708 INFO [BPM-Scheduler:192.168.7.121:1] com.soffid.iam.bpm.job.JobExecutorThread.run No job to execute
When I manually run the task Analize impact for changes on Schrift, Execution log shows
Changes detected for accounts
=============================
NO CHANGE DETECTED
Changes detected for roles
=============================
NO CHANGE DETECTED
Update#2
After many attempts I made some progress. Now when I make some changes in the account, the task named UpdateAccount baklykov#irf.com.ua#Schrift appears, but runs with an error.
At first it was 415 Unsupported Media Type error as I wrote in comments, but now it looks a little different
Throws exception updating object : Extensible object [type = account]
EmployeeEmail: baklykov#irf.com.ua
IsLockedOut: true (log truncated) ...
caused by Unexpected response, Content-Type: null
Update#3
I found out that soffid's request for updating the object was in improper format (all the parameters were passed in the html request instead of putting them in json body)
After researching I found a method's property called Encoding and set it to application/json value.
Now the parameters are passed in json body (that's what I need), but now the problem is that soffid puts all the parameters in json body, including the key parameter by which the object for updating should be determined. My guess this is the reason why the object in the target system is still not updated.
In other words my application expects a request like this:
https://myapp.mysite.com/api/v1/Soffid/Employees?EmployeeEmail=baklykov%40irf.com.ua :
{"EmployeeLastName":"Baklykov","EmployeeFirstName":"Ivan"}
but Soffid sends this:
https://myapp.mysite.com/api/v1/Soffid/Employees:
{"EmployeeLastName":"Baklykov","EmployeeFirstName":"Ivan","EmployeeEmail":"baklykov#irf.com.ua"}
The system should have created a UpdateAccount task in the task queue. Please, verify:
The task engine is in automatic mode. In read-only or manual mode, no task will be created.
If you are updating an account, check the account is not set as unmanaged. In that case, no tasks is created.
Finally, verify the task queue has not held the task up.
Have you checked the engine mode? Look at Main Menu > Administration > Configure Soffid > Integration engine > Smart engine settings
It should be set to automatic.

how to delete post using socket.io mysql nodejs express

I'm learning to do simple messaging app which allows user to add the status and in real time update it to feeds of everyone.
I am using socket.io, mysql, nodejs and express.
User can send message in real time.
In browser startup, it load all data in database.
I'd like to ask how could I delete message based in ID ?
Thanks.
Without knowing how you currently pull the post cant give as detailed of a response, but lets assume you emit that from your socket as well..
The websockets are a persistent connection to the users, because of that both client and server can emit or receive commands. With that knowledge we can now just 'emit' from the 'client' to the 'server' a command that the post has been 'deleted' when the 'client' emits to the 'server' the socket server can then delete the post from the DB, after the deletion has been completed it will then 'emit' to the 'client' who has a listener for 'postDelete' (or whatever you want to call it) that may contain the updated post list OR it could have another call that runs an update post function etc.
** Edit **
To add a bit more to this.
It's important to remember that socket.io is really just a message broker of sorts. It can GET and EMIT messages, you tell it how and what to do for each.
So to the question as to how you would go about 'deleting' the message is really no different then how you would go about it normally
(client) user clicks delete, 'emits' to server
Server is 'listening' for the 'emit' on X command to delete
Server gets command, inside of '.on' for delete is your 'delete' code (will probably be SQL to remove from DB)
After command is run and successful you will then 'emit' from server with the new payload of 'posts'
Client has a ".on" to listen for new or updated 'posts' server 'emits' to this
Client get new 'emits' from server with the updated JSON and updates the screen.

New session entries are being created in database even when codeigniter session library is not loaded. Why?

I am having a rather weird problem with Chris Kacerguis’ CodeIgniter REST Server.
Problems:
1) I am NOT loading the CodeIgniter session library, even then new entries are being created in the ci_sessions database table, everytime I am making an HTTP Request to my REST Api.
2) A brand new entry is being created (and the old entry is NOT being updated) in the db, on every HTTP Request, even when the IP Address is remaining the same.
This is my config.php file:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 0;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = TRUE;
$config['cookie_prefix'] = '';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;
I tried, individually and in combination, the following things:
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 0;
$config['sess_regenerate_destroy'] = FALSE;
and
$config['cookie_domain'] = '.mydomain.com';
But nothing worked.
Is this normal or some kind of a bug? What am I doing wrong? Anyone else having the same problem?
Another thing is that, I am not facing this issue in vanilla CodeIgniter. There, everything is working fine and as expected.
Update
I found something while struggling with the second part of the problem.
Two session entries are being created in the database while making the first HTTP Request - one for the client and another one for the REST Server. From the second request, the client 'version' of the cookie is being UPDATED while the server 'version' is being RE-GENERATED.
For the 1st part of the problem:
As pointed out by #JamesLalor in the comments,
You must either be autoloading the session
OR
You are using some external library which is, in turn, loading the session library.
For the 2nd part of the problem:
The below solution may not be the best, but it worked for me.
Multiple sessions creation problem occurs when:
You have both REST Server and Client within the same CodeIgniter Application directory
AND
Session library is auto-loaded
To the Client, the user is the consumer. A session is created for the user, having the IP address of that user. A cookie is set on the user’s browser with which the session is validated and updated (or newly created) based on the validation.
To the REST Server, the Client is the consumer. Here also a session is created (if both condition 1 and 2 above is fulfilled), but this time, it is for the Client, and this session has the IP address of the server on which the Client resides (if condition 1 above is fulfilled, then it is the IP address of the same server on which your app resides). But this time a cookie could not be set, as the consumer is not a browser. Hence, the session validation fails and a new session is created each time the page loads.
Solution:
REST is stateless and every request should contain all the information required to fulfil the request. Therefore, using sessions (whose sole job is to maintain user’s state) on REST Server is considered a bad practice. It is the job of the Client to maintain the user’s session and pass the required information to the REST Server on each and every request.
Therefore, assuming that you would not be needing session within REST Server, the solution is to remove session from autoload[‘libraries’] list, within autoload.php file, and load the library within the Client constructor (or when you need it).
Sorry for grammatical errors and/or bad English. It is not my native language.

How to have continuous connection with MYSQL?

I have an application in JSP, using MYSQL database and Apache 6.0 server.
Interfaces : Admin and Client
Requirement : Admin should get all the client names who are logged in. There is one text-box, if admin enters any message in text-box and clicks on any client, that message should display on the client browser.
Current Implementation : Once admin clicks on the client name in database I am updating a column named 'status' with the text box value. (Initial value of 'status' column keeping as FALSE).
On client side I have set interval method which is calling a servlet using ajax (every second) and executing a query which checks the 'status' value, if it's NOT FALSE I have a function which shows the retrieved value on the page.
Issue : Due to the one connection per client per second, MYSQL is taking 100% CPU usage and crashing down. I have around 200 clients using the application simultaneously.
I need an alternative and efficient solution for this.
Any help will be really appreciated.

SQL Server 2008 table change (insert/update/delete) notification push on broker

I have a rather complex and large database with about 3000+ objects (tables/triggers/sps combined). I inherited this DB and restructuring it is probably 3-4 years away.
meanwhile, I need to implement a pub sub feature for any insert/update/delete on these tables. Given number of tables and existing queries probably query notification (and SQL Dependency) will not work. What I am looking for is a way to push the changes (what changed in table - like records PK and table name) on the service broker so I can use external activator to then retrieve change,and then use my custom pub sub from that point onwards.
I have pretty much all the ducks lined up except for the way to push change notification on service broker.
Any help/pointers are appreciated.
Thanks.
N M
PS. I did look around for similar postings and did come across a few however, MSDN articles they referred to seem to have all removed - not sure what's going on on MSDN site.
For external activator look at Microsoft SQL Server 2008 Feature Pack- "Microsoft SQL Server 2008 R2 Service Broker External Activator".
For console application (that processes messages) great idea is to drop an eye in codeplex. There is good examples.
To put event notification (notifications, that will be used by external activator service) code looks something like this:
Create Queue ExternalActivatorQueue;
Create Service ExternalActivatorService On Queue ExternalActivatorQueue
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
Create Event Notification NotifyExternalActivator
On Queue dbo.ProcessQueue
For QUEUE_ACTIVATION
To Service 'ExternalActivatorService', 'current database'
To send message in the queue:
Declare #h UniqueIdentifier;
Declare #x xml = '<tag/>';
Begin Dialog Conversation #h
From Service MyTableService
To Service 'ProcessService'
With Encryption = OFF;
Send On Conversation #h(#x)
All steps i done to make it work is here, but just in Latvian :). There actually is almost what you need (trigger that sends messages when data are inserted in table..).