I have just discovered that Apache commons-configuration can read properties from a DataSource, but it does not cache them. My application needs to read properties a lot of times and it is to slow to access the database each time.
I have a Camel application that sends all messages to routes that ends with my custom beans. These beans are created with scope prototype (I believe in OOP) and they will/need to read some properties and a data source (which reads from properties url/name/etc) that depends from the current user from a SQL db. Each message I receive creates a bean and so properties are reread.
Unfortunately, I am not free to choose where to read properties from because now there is another software (GUI) not written by me that is a User/properties manager that writes to db. So I need to read properties from it.
Can you suggest me an alternative?
You could use the Netflix Archaius project, which adds the caching behavior you are looking for as well as dynamic refresh capabilities. Archaius is built around Commons Configuration.
So, rather than subclassing the DatabaseConfiguration, you could use Archaius' DynamicConfiguration, which extends Commons' AbstractConfiguration. This class will cache whatever source you would like, and refresh the properties at an interval you specify using their poll scheduling class.
The only class you would have to implement is a PolledConfigurationSource which pulls data from the database and places it in a Map. Should be pretty simple.
https://github.com/Netflix/archaius/wiki/Users-Guide
Related
This is fairly straight forward with a simple Spring DAO approach. However, using MyBatis, is there a way to setup multiple potential datasources?
The best approach I can think of is to use an ArraList of a Bean each containing datasource.driverclass,datasource.url, datasource.username, datasource.password etc.
The values for the datasources are stored in individual properties files. There could be 1 or 10 of these property files (or more).
So for example, one application startup all the property files would be loaded one at a time into an ArrayList. Then, based on the NAME=value line from the property file, we would know which datasource to hit.
So http:localhost:8080/name=db1
... would access all the data from the datasource configured with the name "09". Each property file would contain:
name=db1
datasource.driverclass=jdbc:sqlserver
datasource.url=jdbc:sqlserver://localhost:1433;databaseName=someDBname
datasource.username=user1
datasource.password=pass1
So the identifier here is "name=db1".
Would the best approach from a MyBatis implementation utilise an ArrayList of Beans?
Here are some leads if you want to keep up with multiple DB:
Anyway, I would say datasources shall be managed in the server confiquration instead of in the App.
Then Mybatis main configuration file must be placed in a location added to the classpath, but outside of the app package, because every new datasource must be referenced there inside an environment element.
And for every user request or session (in case of a web app), the configuration will be parsed because SqlSessionFactoryBuilder.build(reader, environment=NAME); must be called to choose the environment (=> the DB).
I ended up using a hierarchical application.yml file detailing the multitenant connection values, based on a selected tenant code.
We are using the Spring integration FileTailingMessageProducer (Apache Commons) for remotely tailing files and sending messages to rabbitmq.
Obviously when the java process that contains the file tailer is restarted, the information which lines have already been processed is lost. We would like to be able to restart the process and continue tailing at last line we had previously processed.
I guess we will have to keep this state either in a file on the host or a small database. The information stored in this file or db will probably be a simple map mapping file ids (file names will not suffice, since files may be rotated) to line numbers:
file ids -> line number
I am thinking about subclassing the ApacheCommonsFileTailingMessageProducer.
The java process will need to continually update this file or db. Is there a method for updating this file when the JVM exits?
Has anyone done this before? Are there any recommendations on how to proceed?
Spring Integration has an an abstraction MetadataStore - it's a simple key/value abstraction so would be perfect for this use case.
There are several implementations. The PropertiesPersistingMetadataStore persists to a properties file and, by default, only persists on an ApplicationContext close() (destroy()).
It implements Flushable so it can be flush()ed more often.
The other implementations (Redis, MongoDB, Gemfire) don't need flushing because the data is written immediately.
A subclass would work, the file tailer is a simple bean and can be declared as a <bean/> - there's no other "magic" done by the XML parser.
But, if you'd be interested in contributing it to the framework, consider adding the code to the adapter directly. Ideally, it would go in the superclass (FileTailingMessageProducerSupport) but I don't think we will have the ability to look at the file creation timestamp in the OSDelegatingFileTailingMessageProducer because we just get the line data streamed to us.
In any case, please open a JIRA Issue for this feature.
I am very much new to multi-tenancy. We have an application based on Java, Spring, Hibernate/JPA etc. which doesn't support multi-tenancy.
Now, we want to convert that application into multi-tenant one. I have read about multi-tenancy and even wrote one standalone application using hibernate with separate schema approach. Link referred is here.
I think about the logging part which is bound to be changed now as log files will be maintained per tenant(client) now. So, for each tenant a separate log file will be there.Also, log file for a particular tenant shouldn't be accessed by another tenant.
Is there any logging API specific to support multi-tenancy? If not, how should i go ahead with implementing logging in multi-tenant application? What should be taken care of while implementing logging in multi-tenant application.
you can use MDC (mapped diagnostic context) support to route logging for each tenant into a separate file/dir/whatever.
you can read up on the concept here. it exists in slf4/logback and log4j
simply put, you set some property like tenantName in the MDC at the beginning of every request processing according to the specific tenant making the request and then use this property in your logging configuration to determine the log file into which log messages are written.
I'd like to extend/replace the Spring PropertyPlaceholderConfigurer to read from a web server as opposed to properties files.
A bit of background:
I work on a project, and we're finding the number of properties files located on the users systems is getting a little unwieldy. We'd like to replace these files with a 'config server' which will store basic key/value pairs and serve them when the user starts up the app.
To avoid making too many changes, I'd like to change the way the PropertyPlaceholderConfigurer finds properties - rather than implementing an entirely new way to manage properties. So on startup - Spring will read all properties from a url, and feed these into my spring config xml in the same way as it would have with actual files.
Bonus!
If anyone has any ideas how to do this where properties are reloaded from the server only when they change, will get bonus points (I have no idea if I have the ability to assign bonus points, but I'll try!). That would be a 'nice to have, if there's not too much effort involved' solution.
Spring's PropertyPlaceholderConfigurer (PPC) already uses the Resource interface to specfiy the location from where to read properties (via the setLocation(Resource) method inherited from PropertiesLoaderSupport.
There is an implementing class of this interface called URLResource which probably does what you want. You could simply create a PPC and set the location property with a bean of this type to load the properties from a URL instead of a file. This class also supports file:// type URLs, so you could switch between on- and offline properties loading depending on the URL you use.
I am wondering if the below is possible in Spring
Read a property file using spring - this file has a list of jms queue names
Make spring loop on the above list and define beans that define Apache camel routes from that queue to a file
I could just create the routes using java code on the apache camel context, but wondering if it is possible through spring.
Reading a property file in a Spring XML wiring file is easy; e.g. using a PropertiesFactoryBean. However, the second part of the problem cannot (I believe) be solved without writing a significant amount of Java code.
I suggest that you read Section 3.8.3 of the Spring Reference that describes how to write your own FactoryBean classes. Another possibility is to create a custom Java configuration bean as described in Section 3.11. There may be other possibilities too.
Warning: none of this stuff is particularly straight-forward if you are coming at it for the first time.