Managing concurrent access to an Apache Derby database - java

I have an Apache Derby database running (in networked mode) inside a java swing application, I connect to it through direct JDBC calls via a java client application.
This is all very good and works great however I know have an additional requirement to implement concurrent licenses for this client/server application.
Ideally a user with a single user license should be able to have 1 client app running on a laptop and also a second client app running on a desktop and be able to connect to the server from both.
I don't have the luxury of a web server so I am wondering if my only option is to use the "maxthreads" runtime property in Derby and essentially force the user to have to log off the laptop say if they want to then use the app from their desktop.
If I leave the timeslice property to 0 then will a call to getConnection timeout so that I can display a message to the user explaining that they need to disconnect one of the client apps.
Are connection threads a reliable way of doing this?
Am I missing another solution?

If I understand the question correctly, you have user-locked licenses and want to prevent a single user with a single license from accessing the "server" from more than one instance of the client at a time. Your "server" is simply a database and you don't want to create an application layer on the server side.
I don't really like your initial suggestion of using the thread pool and connection timeout to enforce licensing constraints because both of those things are used for other purposes.
Instead, to solve this I might consider requiring the user to enter their license number into the GUI the first time they use it. This can be saved in the user's home directory for subsequent starts of the GUI. The same would happen if they start the GUI for the first time on another machine. Then, for each transaction the GUI makes with the database, it would first update a licenses table or similar to indicate the user's license is currently taking part in a transaction. Wherever the same license is already in the table, marked as active, or similar, the GUI would reject the transaction and display to the user their license is already in use by another client.
If you like this idea, think it through farther than I have. I can see some errors in logic locking users out permanently :-)

It seems like you want to make the action of "logging in" and "logging out" of the database explicit, so perhaps you may want to have a special table in the database where your application writes a record when you log in or out.
Then your application can query that table to find out if other copies of the application are currently logged in.
You might want to include additional fields in the table to track the date/time when you logged in/out, the hostname and IP address of the client which performed the login/logout, etc.

Related

Ways to Implement Tomcat Server-Wide Persistent and Changeable Variables Across All WebApps

Production Environment: Tomcat 9 on CentOS 7 x64, mysql/mariadb 5.5x
Testing Environment: Tomcat 9 in Eclipse on Windows 7 x64, mysql 5.5x
I'm a Tomcat newbie looking for the best method to have server-wide variables readable/writable from all Webapps for things like MaintenanceMode(on/off) and MaintenanceMessage, etc.
These are the variable properties I'm looking for:
Readable/writable from all instances of all java servlets on all webapps.
Value persists after OS, Tomcat, or Webapp restart.
I must be able to change the value of it from one webapp and then all other webapps recognize the change quickly, ideally without restarting.
Ideally I wouldn't want to read the variable from disk on each server request. In case server is getting DDOSed or something.
Ideally the solution is OS independent.
If it's a disk file solution please recommend a place for me to store the file.
I'm new to Tomcat so some detail in any answers would be appreciated or links to detail. I'll probably be using a servlet on it's own 'admin' webapp that's only accessible through SSH-tunneling, etc, to set the variables. Then the public webapps would respond to any changes, like showing a maintenance message while I backup databases. I could also possibly change the variables using linux commands if needed.
If I stored the server variables in a database that could be fine but I wouldn't want to read the DB on every single request most likely, and when I change a variable I'd have to once again notify every webapp/servlet that something was changed and to re-read the DB.
Thanks for any help.
I implemented this recently in the form of "system messages", some of which are for maintenance. But the effect is the same. We had some additional "requirements" which helped us form the solution. These may or may not match up to your expectations/desires:
Multiple-server coordination
Immediate synchronization was not necessary
We used our relational database for the actual data storage. A single table with "system messages" and a few other fields such as when the messages became effective (not_before DATETIME) and when the messages became ineffective (not_after DATETIME).
On startup, the application reads the system messages table to find the currently-valid messages and stores them in application scope, including their validity dates. Whenever we want to show them on the screen, we check each item in memory and evict any that have expired. This is pretty fast.
Every X minutes (e.g. from cron), we make a request to a special servlet (on each server) that re-loads the system messages from the database. We protect that servlet by only allowing requests from certain IPs, so DOS is not an issue.
Not only can we add a system message from any server in the cluster, but we can also add one by writing directly to the database. That may be advantageous if you don't always want to use your application to generate these events.
You can change the value for X to anything as low as 1 (minute) if you are using cron. If you use some other kind of system, you can probably get updated even more often. I would seriously reconsider your requirement of "immediate" recognition because that requires a system that has much worse performance.
If you can guarantee that only your application can generate these changes, and you have a list of all other servers in the cluster somewhere, you could theoretically ping them all with the new message (or notify them that a new message exists and it's time to update their message-list), but that kind of thing is better-done with an orchestration tool such as Kubernetes, and we are getting a little out of scope IMO.

Informing Java Application about changes in database

I'm trying to build a task-manager application. Two or more client applications should be able to change (such as mark off or change the title etc) certain tasks stored in the database over the web.
While creating the requirements, the following question came up:
How is it possible to inform client applications (Android Apps, Java-Applications on a Mac) about changes in the database, without constantly checking the database? I planned on storing the data objects in a SQL-Database on a Webserver.
Should I use another database? What is the standard way to go right now in SE world? Any keywords for me or explanations would help!
Firstly, make sure you are not accessing the database directly from the client applications, that's a very dangerous route.
Secondly, as for your requirement it looks like you want a server side push notification.
As far as I know there are 3 ways to do this.
Check updates from the server every X seconds (if you don't have too many clients that needs to be notified this way is okay to go)
Use HTTP long polling.
Use WebSocket to keep a long lasting connection between server/client applications.
For mobile devices though, if you want to be notified even when the app is closed, take a look at all the push notification frameworks available out there (e.g. FCM/GCM).

Launching test SMTP server from ColdFusion

We are in the process of creating a training mode for our ColdFusion (9) sites.
The system will allow our users, after logging in, to switch from production mode to training mode by clicking on a link.
When they switch, the data-sources will be switched allowing the data to be safely modified.
We are also going to implement a test SMTP server, using the SubEthaSMTP Java project, in order to capture the emails that are sent from the training mode and display them to the user in a web page.
We can launch the SMTP server as a stand alone process or service without much trouble.
The nicer solution would be to launch server as part of the ColdFuson runtime at the point that the user switches to training mode.
We would create a true Java thread that would persist on a Server level scope for the length of any training sessions and then some arbitrary time out period. If the server times out and a new training session is initiated we would initiate a new SMTP server.
My essential question is, therefore, is it a bad idea to run an ongoing thread in the ColdFusion runtime this way?
I can't see a problem with doing this, although you ought to test to see what resources SubEthaSMTP uses and make sure it's not going to cause you issues. It looks to have minimal dependencies (essentially just SLF4J, which ColdFusion 9 & 10 already provide)
From the example page it looks to be pretty easy to set up and drop into a long-running scope. I think you're right to pick the server scope, as you may have problems using application or anything more volatile, as there'll be a situation where application scope would timeout and be reset, but you'd loose all references to the Mail Server instance.
Please update the post with your findings, as I'd be interested in seeing what you find.

How to create java desktop application with offline and online database, syncing periodically?

I want to create java desktop application, which stores it's data offline in a database (not just some config files). The application should work fine when the user is offline. When the user becomes online, the offline database should be able to sync with the online master.
Any ideas which technologies can be used to achieve this?
This has been discussed on stackoverflow a lot and it usually boils down to: don't roll out your own solution - This is a very specialized field - Look up SymmetricDS. It does what you want.
One of my fav discussions is Strategy for Offline/Online data synchronization
Use one of the available pure java DB implementations as a local DB. Use any other DB as a remote one.
Implement logic that tries to connect to remote DB and fall backs to local one on failure. If it connects successfully to remote DB implement the data synchronization.
When the local application operates, it should not only change database, but also log the changes. That changes are sent to the server when the connection is available. Also, the application receives logged changes stored on the server (from other application instances).
The main problem is how to merge changes made by different instances. There can be 3 variants:
1) Each application instance can modify only its private part of the whole database. Your are lucky, no merging needed, and server can store only logs and not run the whole database.
2) modifications always can be merged automatically (for example, application can add a value to a common variable, but cannot set it directly). The server runs the whole database, accepts partial logs from clients, generates its own log and sends it to clients.
3) Clients are allowed to do arbitrary modifications. This leads to potential conflicts. In case of conflicts, one of conflicting changes should be rejected. That means, that if a client made local modifications, that modifications can be rejected later by the server. The user interface must reflect this issue. In the rest, this is similar to the variant 2.

prevent access to mysql database from unauthorized software

i am writing an application in java and i want to enable it to access a mysql remote server.
my problem is that if the application have the user name and password someone can take them and use my db with a different software.
is there a way of preventing it ?
UPDATE
i found this workaround for connecting to a remote MySQL database from an android device.
you put a service in the middle. like a php page that code the data in JSON format which the android app gets via http.
here is the example i found :
Connecting to MySQL database
Having the username and password is designed specifically to grant access to the database. That's the whole point.
You could go to some extra lengths like restricting database connectivity to specific hosts, so at least your paying customers get access to the database and no else can access it, but your customers might choose to use different software to access the database. There's no way around it except licensing terms.
What you could do is run an intermediary program on your own hardware that connects to the database and restrict access to the database to software that is under your direct administrative control. Your program would validate all requests from software under control of your customers and allow the queries that you want to allow and refuse (and log) the queries you do not have to allow. (You do not need to send raw SQL data back and forth -- you can do any amount of processing on the data and queries.)
You can setup JDBC Data Source on your application server. Here you can see example for Oracle Glassfish.
So, your credential won't be used in your code/resources.
If you are saying that you have an application trying to access a MySQL remotely (not in the same box), then i think you need not worry, as the connection that will be established by your application codes will not expose the username and password when it is trying to authenticate and authorize itself to the MySQL server.
You can limit the access to the MySQL-server so that only certain IP-addresses or IP-ranges have access to it.
As a side note, make sure that the user you use in your application only has the needed permissions to the database. For example, the user might not need to be able to create or delete tables. You can even specify permissions for the user on table and column level.

Categories