I'm currently working on an admin panel for some java programs I've written. The Java Programs are currently getting controlled by their own cfg files. My idea to update the configs via the control panel is to change values in the control panel, save those changes in a database via mysql and then write a "config updater" which keeps fetching the database entries every couple of seconds and then writes the changes to the cfg files. I'm just wondering about the efficency, is this a good approach or are there way better and more efficent ways?
It really depends on what you actually want to achieve.
If your program is reading the cfg files on demand, meaning, that you can change them and the results are effective immediately, you would just fetch them on demand from the DB as well.
If the cfg files are more or less statics, you might consider using a .properties file instead (or even a Config class containing only static and final fields), or, if you want to stick to the database, you could use the Singleton approach and just read it after startup into the Singleton.
In the end it's almost down to opinion and use-case. If the config should be configurable by the customer / end user, it might be better to use a database anyway. But as a developer, I frankly don't care as long as it's documented where to configure it.
Related
Background : I don't want to hardcode properties in a java constant file, coz every time I want to change to one of the property_value, I have to build and deploy the entire code again. I don't even want to keep them in application.yaml/application.properties file, coz my properties are huge in numbers(100s). So, I have decided to maintain properties in a properties table in oracle DB.
I can think of two approaches :
Read the property value as and when required by firing a sql query.
Load all/part of the properties at the time of starting application and have global point of access by caching them.
As I need few of the properties in the beginning itself, I want to go with approach number 2.
I wanted to go for singleton bean, but this requires me to know all of the keys(property_names) in the beginning itself, and makes the singleton look ugly having 100s of member variables. Here I was planning to fire query by using pre-construct function of spring bean. The main problem here is the bean requires to be changed every time I add/delete properties from the properties table.
Another approach I could think of was to go with a Map<String,String> as both the property_name and property_value columns of my table are of VARCHAR type. But the question is how can I get global point of access to this map ?
Any better approaches much appreciated!
Many thanks in advance
If you deploy your app on web server you can take advantage of it. Many of web server supports changing configuration on the fly (using web console) such as JBoss EAP.
The other idea is to build your own properties lib. Create a function which read the data. I'd prefer using NoSQL database than RDBMS because of lightweight, great performance and scale very well. I wouldn't use caching unless it persisted somewhere and good on availability.
I've heard about Spring Cloud Config to externalize configuration but i never deep dive into it.
Some of us uses Apache Commons Configuration that support properties reload. Take a look at this thread.
I am working on a spring MVC web application. There is some master data for example currency code INR which I require on jsp page to compare with data from form bean. So which should be the correct place to store master data. Should it be in property file or do I need to fetch it from database and store it in any of the scope ?
Any kind of help will be appreciated.
If you don't expect to change data often then the property file is a fine place as a start. It is the simplest in terms of development effort. But note that to change the data you will need to restart the application.
Also if the application is running on multiple machines then each machine will have separate properties file. So you will have to edit properties files on all machines.
The database is better if you want to expose functionality to update the configuration to end-users. Also, the database will act as a single source of truth, no matter how many application nodes you have.
By currency codes, do you mean data like https://www.iban.com/currency-codes.html ?
In that case, it is a small amount of data that does not change often.
So the properties file is ok. To inject properties as a map (unknown number of keys, unknown exact key values) you need to use #ConfigurationProperties as described in https://docs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/htmlsingle/#boot-features-external-config-loading-yaml
I would go for a database if it is used by your project for other purposes. Otherwise, I would go for the properties file.
As said in the comments, business data belong in the database, even if you change them every other year. Property files are a great place for technical properties, especially those that are required before you load the Spring context. Those might be database credentials, logging level etc.
Consider that if you start to load-balance your application on different hosts, you'd have multiple property files, too. Imagine you forgot to update the currencies in one of them, you're gonna screw up the consistency of your whole database, when each instance of your app calculate different prices.
You may consider using yml/properties files with Spring Cloud Config. It's simple enough to use and it will give you a way to update your properties in runtime, without redeploying or even restart. So don't forget to enable Spring Actuator endpoints and get familiar with #RefreshScope annotation.
Is there a way to log all database tables (and maybe other objects) that the application running within Tomcat reads from/write to? All of the database access is performed either via Hibernate (wired through Spring) or Sql2o.
We are in process of migrating a legacy database, and it would be nice to automatically separate tables that are actually used from the ones that are pure legacy (and we've got lots of those!).
Thanks!
You can create new Aspect since you are already using Spring, and monitor all your read/write services, so every time any of it is called, you can log it.
It should be quite easy, define new aspect (f.e. MyAspect), define before/after or round actions (which will log your table names somewhere), and just put the annotation on your services (#MyAspect).
Another way is to create triggers on your tables (not sure if that is an option), but I'd preffer an aspect... It's much cleaner approach.
Given I have a simple task: process some piece of data and append it to the file. Its ok if I dont have exceptions, but this may happen. If something goes wrong I would like to remove all the changes from the file.
Also, may be I have set some variables during the processing and I would like to return their previous state too.
Also, may be I work with a database that doesn't support transactions (to the best of my knowledge MongoDB does not), so I would like to rollback it from DB somehow.
Yes, I can fix the issue with my file manually just by backuping the file and then replacing it. But generally looks like I need a transaction framework.
I dont want to use Spring monster for this. Its too much. And I dont have ELB container to manage EJB. I have a simple Java stand-alone application, but it needs transaction support.
Do I have some other options instead of plugging Spring or EJB?
If you don't want to use spring, try to implements a simple Two-phase commit mechanism: Two-Phase Commit Protocol
I am no Java expert but this sounds simple.
In fact I would not use transactions in an ACID compliant database since it doesn't sound like the right action.
Instead I would write to a temporary file, when your records have been written merge with the original file. That way if some records cannot be written to the file for whatever reason you just drop the old file and merging and saving the new file will be atomic within the program's memory and the OS's file system.
We have a utility spring-mvc application that doesn't use a database, it is just a soap/rest wrapper. We would like to store an arbitrary message for display to users that persists between deployments. The application must be able to both read and write this data. Are there any best practices for this?
Multiple options.
Write something to the file system - Great for persistence. A little slow. Primary drawback is that it would probably have to be a shared file system, as any type of clustering wouldn't deal well with this. Then you get into file locking issues. Very easy implementation
Embedded DB - Similar benefits and pitfalls as just writing to the file system, but probably deals better with locking/transactional issues. Somewhat more difficult implementation.
Distributed Cache - Like Memcached - A bit faster than file, though not much. Deals with the clustering and locking issues. However, it's not persistent. Fairly reliable for a short webapp restart, but definitely not 100%. More difficult implementation, plus you need another server.
Why not use an embedded database? Options are:
H2
HSQL
Derby
Just include the jar file in the webapps classdir and configure the JDBC URL as normal.
Perfect for demos and easy to substitute when you want to switch to a bigger database server
I would simple store that in a file on a filesystem. It's possible to use an embedded database, or something like that, but for 1 message, a file will be fine.
I'd recommend you store the file outside of the application directory.
It might be alongside (next to) it, but don't go storing it inside your "webapps/" directory, or anything like that.
You'll probably also need to manage concurrency. A global (static) read/write lock should do fine.
I would use JNDI. Why over-complicate?