18 octobre 2013

Configuration Management JSR

I recently discovered project to start a JSR for Configuration Management. Mike Keith introduced this project at JavaOne, you can download slides for his presentation here. I wasn't aware so didn't attend the live talk, but reviewing the slides I have few comments.

Proposal (afaik)

Scope for such a JSR is difficult to establish. If you want to embrace the existing tools, there is overlap with generic platform provisioning. I don't think this is a good idea to consider this until there's a reasonable consensus on application-level configuration management. Looks like this is also the diagnostic for this JSR.

The current state for JavaEE configuration is "JNDI" : if you need to inject some resources / parameter to an application, you have to provide some container-specific xml file in your WAR archive. This suppose Ops will unzip the WAR, edit xml to put production resource binding and credentials, then re-archive and deploy using container-specific commands. Nobody never did this. So this is a great idea to review this and provide something to better match actual practices and tools.

Also have to consider the DevOps impact on development/deployment practices.

Contract for configuration management is also complex to establish. Reviewing slides, the proposal seems to be to package application configuration in a CAR (configuration archive).


I think this is a very bad idea. For the same reason Ops don't unzip WAR to edit xml files, they won't do this to create CAR files. Ops tools and practices are based on scriptable solutions from system shell. I don't think we will see JavaEE apps packaged as RPM/DEB system packages, at least because Java is supposed to "run everywhere", not just on Linux distros. But a configuration management JSR must primarily focus on Ops practices, not on JavaEE developers. JSR use to define Java based API, I think this specific JSR must NOT use Java as primary language. My main concern with a java-based approach is that this will result in a new java.util.prefs.Preferences nobody is using.


My vision

I'd prefer the JSR to define a REST API application container (or platform as a service) have to expose to allow defining the configuration for an application. REST is neutral, well supported both from Java tooling and base script shell (using curl).

So, you can imagine a REST endpoint on your application server that let you define an "application" (unique ID) and bind server resources / configuration parameters to this application. Application server is responsible to implement actual persistence.

Deploying an application would then be :


  1. create the application with unique ID
  2. set application configuration 
    • resource bindings (JDBC DataSource, JavaMail session, JMS queues, etc)
    • simple parameters
    • structured parameters (? - see later)
  3. deploy WAR/EAR for application ID


Application configuration has to be persistent : it will survive application restart and redeployment, as long as application unique ID is unchanged. It's also idempotent: binding same resource twice don't result in a duplicated resource. This is a requirement for infrastructure automation tools (like Chef/Puppet) to work in this context.

Without any surprise, you probably notice how this proposal mimic CloudBees configuration management. We also support cloudbees-web.xml and some of us like it, but I consider this legacy. Using SDK to bind a Database to my application, whatever application server I'm using - Tomcat, JBoss, Glassfish, Jetty - and getting it injected as a JNDI DataSource is awesome.


How does application access configuration ?

Based on slides, JSR proposal defines a new API for application code to access configuration. So, you'll have to wait for all frameworks to be updated to benefit this API :-/

To workaround design issue for JavaEE to miss a configuration API, most framework rely on placeholders, the common denominator being support for system properties. I never have seen a JavaEE application to use String declared in JNDI, but I not a bunch of apps to get runtime settings from system properties. For adoption of a configuration management JSR, and immediate support on most frameworks, system properties must be considered as first-class citizens in configuration land.

Injecting a simple parameter in an application should result in getting the equivalent system property set. With system properties, you already can manage a bunch of use-cases. I'm not sure there's actual need for structured parameters. This could be addressed by JAXB / JSONB data binding anyway.

Conclusion

I'd be very happy to contribute this JSR. I've been looking for an "incubator" page for it but can't find this on jcp.org. I'm not sure then how expert group is established, but if I can join I'd be very happy to compare my point of view with others and help as much as possible to make this JSR a useful one.


7 commentaires:

Nicolas Peru a dit…

"This suppose Ops will unzip the WAR, edit xml to put production resource binding and credentials, then re-archive and deploy using container-specific commands. Nobody never did this."

I really need to talk to you about what I have done that last year...

Werner Keil a dit…

You have no idea. I have seen numerous projects where (mostly Offshore providers) O(o)ps did exactly that. Open a WAR with tools like WinZip, if part of an EAR then cascading, changing values and then packing up all files and deploying them again;-/

This must be avoided, you don't want to rebuild a WAR just to move it from Preprod to Prod or across different tenants.

Nicolas De Loof a dit…

Ops have to find a workaround to manage configuration without support from the spec/container. I've seen many apps where the properties file to define production configuration were sent by email to Ops then installed on servers. No version, no diff with previous version.

You know what ? We got regressions :P

Unknown a dit…

Hi Nicolas, join the java-config project on java.net. There is not yet an official JSR running. Also Mike Keith will not be able to lead it, but I am sure there will be one.
I am currently discussing with my bank (Credit Suisse), if I can lead that JSR.
I will activate JIRA on the project, so we can add features and requirements there...

As a last note, I would be very careful defining constraints that must be implemented by all vendors. I would try to stick on a flexible and distributable config mechanisms, supporting different formats and types, and of course being also injectable. Vendors in that way may profit from the new mechanisms, but are not constraint be them. The DevOps topics I would tend to say another JSR should define that.

Nicolas De Loof a dit…

@Anatole I don't care about configuration injection in apps. We already have the required techniques for this, no need for a new one.
My concern is how to define this configuration on an application, so the DevOps topic. If this JSR don't cover this, I don't have any interest on it. Configuration management is a deployment and operation topic, not application code and design one

Arjan Tijms a dit…

The deployment and application ID stuff, and then sending configuration to that application ID looks a little like something Java EE used to have, but which was pruned: JSR 88 (https://jcp.org/en/jsr/detail?id=88)

JSR 88 for reasons that are not 100% clear was never really used.

There's some speculation that it was never used because it combined deployment and server specific configuration, while people primarily wanted just a deployment standard.

On the Java EE mailing list and at JavaOne it has indeed been discussed if "simply" using REST wouldn't make the things JSR 88 attempted to address better. (Obviously a server can't be started via REST though).

Nicolas De Loof a dit…

JSR 88 was never well implemented not used as it was container specific. A server SHOULD be started by a rest call, see how docker daemon let you run a full container !