How to manage configuration data in large projects? - configuration

As software projects grow they inevitably pile up a lot of configuration data. Each new module, library or framework can have some. Data can have many form such as XML, properties etc. But they usually can be located at in-code defined places. Is there any good practice saying how the configurations should be structured and otherwise managed?

No matter the technology - whether .Net, Java or whatever - a large project will warrant the use of a shared/central configuration provider/manager on which different modules/libraries depend.
For .Net a GAC registered configuration manager library is a good option which exposes the configuration settings from a shared .Net app config compliant configuration file. If multiple processes/app domains use this shared configuration their own app configs can include the central config file and thus use the central configuration manager.
For Java a similar approach is probably advisable, as long as the application configuration library is available on the classpath of each application. In Java's case a lot of the configuration itself will of course be contained in the code or xml files (think spring) of a library itself, but by using a property placeholder one can easily transpose values found in a central properties file so that it is available at runtime/application startup.

Related

Can I use Teacup to manage custom offline Tcl code

I'm trying to figure out a good way for my company to have a local repository/package manager (something a little more user friendly than git). I like Teacup and we are using ActiveState Tcl anyways (Tcl 8.5, we have legacy systems using this version).
Can I use Teacup to make my own offline package manager repo? Sort of like how you can do that with Anaconda in Python. It has to be totally offline but I want to be able to upload packages to it when I make them and let Teacup handle the installation of them for other users in my company.
I've read through this page a little bit but it is missing some content.
You are looking for the server-side component to the "teaparty": teapot as the server providing for the teacup client:
https://wiki.tcl-lang.org/page/Teapot
While there is a dedicated teapot (server) implementation available from ActiveState, the client/ server protocol is straight forward: It is about generating markup (HTML) resources delivered via HTTP (containing table DOM structures) and processed by the teacup client. As always, these resources can be generated statically or dynamically, or anything inbetween.
Watch the examples at:
http://teapot.rkeene.org/index.html
Better:
view-source:http://teapot.rkeene.org/index.html
Assuming your Tcl projects are hosted using some SCM repo, you may provide some repository (CD, pipeline) action to produce a static resource structure served by a HTTP server of your choice? The original teacup client can be used against this resource collection.

Connectors in Activiti BPM

Currently we evaluate Activiti as a possible Open Source Business Process Engine. One important requirement is an easy integration of external systems (ECM, CRM, SharePoint, SAP...) within the processes. During research I found some articles claiming that there are no build-in connectors to other systems. The only way to interact with external systems is to invoke java classes (see http://forums.activiti.org/content/how-create-connector and http://books.google.de/books?id=kMldSaOSgPYC&pg=PA100&lpg=PA100&dq=Bonita+Open+Solution+connectors&source=bl&ots=uwzz5OSten&sig=h2wf0q5J3xAxwN3AZ7Vondemnec&hl=de&sa=X&ei=uwBYUtehHoTqswacrYHgDQ&ved=0CIUBEOgBMAc4Cg#v=onepage&q=Bonita%20Open%20Solution%20connectors&f=false)
How complex is the integration of external systems in Activiti processes? Is it true that there are no bulid-in connectors? This would be a showstopper-criteria for us.
best regards and thanks for you reply
Ben
Currently (as version 5.14) Activiti has direct connection to
Alfresco for document repository
Drools for rule tasks
LDAP for groups and users
Mule for sending messages
Camel for sending/receiving messages
To integrate any other external system you need to use Java Service Task, where you can use Java classes to delegate workflow to your external system. These Java classes can take variables from your workflow, can direct to one of its outgoing flows and of course you can use any capability of your external system.

Production vs QA configuration

Time and again I am faced with the issue of having multiple environments that must be configured individually for an application that would run in all of them (e.g. QA, regional production env's, dev, staging, etc.) and I am wondering what would be the best way to organize different configurations?
Would it be in the database? Different configuration files per environment? Or maybe the same file with different sections/xml tags? How would these be then deployed? Embedded within the app? Or put manually in after installation to be modified in-place?
This question is not technology-specific - I've worked with .net and Java, web-apps and desktop apps and this issue comes up time and again. I'm looking to learn different approaches to maybe adapt a hybrid to address this.
EDIT: There's one caveat that I must point out - when configuration is part of the deployed solution, it is generally installed under root user on the host. In large organizations developers usually don't have a root access to production hosts so any changes to the configuration require a new build and deployment. Needless to say this isn't the nicest approach - especially at organizations that have a very strict release process involving multiple teams and approval levels... (sigh I know!)
Borrowed from Jez Humble and David Farley's book "Continuous Delivery (page 41)", you can:
Your build scripts can pull configuration in and incorporate it into your binaries at build time.
Your packaging software can inject configuration at packaging time, such as when creating assemblies, ears, or gems.
Your deployment scripts or installers can fetch the necessary information or ask the user for it and pass it to your application at
deployment time as part of the installation process.
Your application itself can fetch configuration at startup time or run time.
It is considered bad practice by them to inject configuration files in build and compile times, because you should be able to deploy the same binary file to every environments.
My experience was that you could bake all configuration files for every environments (except sensitive information) to your deployment file (war, jar, zip, etc). And you design your application to take in an extra parameter when starts, to pickup the right sets of configuration files (from your extracted deployment file, or from local/remote file system if they are sensitive, or from a database) during application's startup time.
The question is difficult to answer because it's somewhat vague. There is no technology-agnostic approach to configuration as far as I know. Exactly how configuration is set up will depend on the language/technology in question.
I'm not familiar with .net but with java a popular approach is to have a maven build set up with different profiles. Each profile is specific to an environment. You can then define different properties files that have environment-specific values, an example from the above link is:
environment.properties - This is the default configuration and will be packaged in the artifact by default.
environment.test.properties - This is the variant for the test environment.
environment.prod.properties - This is basically the same as the test variant and will be used in the production environment.
You can then build your project as follows:
mvn -Pprod package
I have good news and bad news.
The good news is that Config4* (of which I am the maintainer) neatly addresses this issue with its support for adaptive configuration. Basically, this is the ability for a configuration file to adapt itself to the environment (including hostname, username, environment variables, and command-line options) in which it is running. Read Chapter 2 of the "Getting Started" manual for details. Don't worry: it is a short chapter.
The bad news is that, currently, Config4* implementations exist only for C++ and Java, so your .Net applications are out of luck. And even with C++ and Java applications, it won't make pragmatic sense to retrofit Config4* into an existing application. Because of this, I'd advise trying to use Config4* only in new applications.
Despite the bad news, I think it is worth your while to read the above-mentioned chapter of the Config4* documentation, because doing so may provide you with ideas that you can adapt to fit your needs.

Implementing a virtual file by overriding Win32 File API

Is there any way to override Win32 File API such as CreateFile()? I want my app to see a virtual file solely for my app, however, the virtual file does not exist actually.
There exist two approaches - with a kernel-mode driver (documented one) and without such driver (a hacky way).
With a kernel-mode driver you have two ways - (1) create a virtual filesystem driver (or take existing one) and (2) create a filesystem filter driver (or take existing one). Driver development = a year or so of work to do right and completely. Driver development is fully documented in MSDN.
Without a kernel-mode driver you need to employ API hooking. Libraries such as Detours, MadCodeHook and Boxedapp SDK do this (and let you do this as well).
Hooking an API topic is quite large to describe it here fully, but there's a good CodeProject article on this topic.
System-wide? Bad idea. If it's just your app, don't use the standard APIs and implement it yourself. But if the data must persist between sessions, you'll have to store the data somewhere (file, registry, etc.).

Application configuration files for Glassfish/Java EE 5 web services

I am trying to write some simple Java web services so we can call Java code from .NET. So far, I got a proof-of-concept working under Glassfish. Pretty straightforward when the IDE does all the work.
Now I'm really bogging down on stuff in Java that should be really simple. For example, I want to externalize my configuration so I can change stuff like connection strings/usernames/application variables/etc without recompiling.
In .NET, you would just stick some strings in the web.config file in the root of the web site and use: ConfigurationManager.AppSettings["whateverIwant"];
I can get java.util.Properties to do what I want (from a standalone client), but I can't figure out where to put the .properties file and how to get the path to it from within the web service.
I need my approach to work within WebSphere Application Server as well. Thanks!
As others have mentioned, it greatly depends on the container, but almost always dynamic configurations are stored in a database instead of XML or .properties files.
As I see that this is just like a proof of concept, here's a quick and dirty solution: (don't do this for production code) use System Properties.
Disadvantage: with every change you need to reboot the container, but you don't need to recompile the app.
To use system properties in Glassfish you can go to the section "Configuration -> System Properties" and add properties there. Then from inside your application just call
String myValue = System.getProperty("myProperty");
To get the value. All java applications support these properties, but I don't know how to configure them in Websphere.
Alas, Java EE has a giant hole in the head when it comes to application configuration.
Your best bet is to either:
use JNDI to store config in the application server environment. This is hard to do portably, painful, and an absolute nightmare for the user to do any configuration. Configuration UI depends on which app server and version is in use and may be a command-line-only utility specific to that app server.
Use the Preferences API to store your configuration, and produce your own UI to edit it. This is OK ... except that you can't control when your settings are flushed and re-inited. Some app servers will do this when your app is re-deployed, which you probably don't want.
All in all, the situation absolutely stinks. There's no clean, sensible way for an app server to provide an app with a simple properties map and UI to edit it using the app server's admin tools.
I tried to work around this using web context parameters, but found that they too were buggy. Glassfish was ignoring more than the first web context parameter that was being set, and they were hard to access without having a servlet context so you couldn't really get to them easily across the whole app.
If anyone has a better answer I'd love to hear it, because the situation as it stands seems downright amazing for a spec that's been through several major iterations.
see also: Storing and editing configuration for Java EE applications
Application configuration is unfortunately container dependent. In general you access your configuration through JNDI. The approach I've recently used was the following:
Make a database available to your app (through JNDI, use the Glassfish database "wizard"). This is part is container dependent.
Create an entity bean that deserializes your settings from the database. The simple solution here is to have something like this:
#Entity
public class Setting {
#Id
private String name;
private String value;
...
}
Then it's a question of doing em.find(Setting.class, "whateveriwant").getValue(). Alternatively, you could create a single entity bean with all the settings as attributes.
Either way, this approach reduces the container dependency to a minimum.
The best solution I've found so far is "EAC4J (External Application Configuration For Java)". I've used successfully in many projects.
Put the following code in the contextInitialized method of a ServletContextListener:
ServletContext sc = sce.getServletContext();
Properties systemProps = System.getProperties();
String path = sc.getRealPath("WEB-INF/application.properties");
systemProps.load(new FileInputStream(path));
This reads from application.properties from the the WEB-INF folder of your web app when it starts. This will require a restart every time the configs change, but in my opinion, that is as it should be.