Saturday, May 31, 2014

Use Case Summary from Google Groups

Use Cases

In todays blog, I am summarizing the use cases as discussed in!forum/java-config. I did only some minor rework on the original posts and hope to still reflecting the essence right.

Configurable Priorities

The configuration system in DeltaSpike uses, what they call, sources Configuration hereby comes from several sources :
  • System properties
  • Environment properties
  • JNDI values
  • Properties file values (default filename is "META-INF/")
These sources have a default priority (System first…. properties file last) that can be changed. So we could easily say "by default, the WEB-INF/classes directory is a source that has a priority lower that an external file". This way, by default, if there is a config file within a war, it will have lower priority, meaning Java EE components will behave as they use to. By adding an external source this (defaults) can be overriden or extended. And of course, this default behavior can be changed.

 Configuration comes from different sources.
→ Configuration must be combinable.
→ Configuration must have different priorities that may taken into account, when combining configuration.

Configurable Overrides

Overriding behavior must be configurable, e.g. refer to the way of the Jersey team does things. You can register components and given them a priority. This approach would allow us to provide a default chain of sources of configuration properties and to allow the user to specify his own chain.

→ Configuration can be evaluated by a complex combination of sub-configurations or providers (e.g. a chain of responsibility)
→ Different environments may require different combinations in place

Multi Tenancy

In multi tenancy setups a hierarchical/graph model of contexts for configurations is required. For example there might be some kind of layering:
  • Layer 0: Default App configuration
  • Layer 1: Tenant specific configuration
  • Layer 2: User specific configuration
Configurations made in the tenant or user layer override the default app configuration etc.

→ Configuration must be orgainizable in layers that can override/extend each other.
→ The current environment must be capable of mapping tenant, user and other aspects, so a corresponding configuration (or layer) can be derived.

Scenario Operations

Current support of Java EE for operations (e.g. PaaS offerings) is weak. Also corresponding providers may not be fully compatible, which makes it more difficult to move applications between providers or different offerings/products within the same provider. Hereby a provider requires an extension to the EE runtime model, where all relevant deployment configuration can be controlled by an external source, managed by the provider and consumed by the EE platform. Basically if one deploys a java application a standard way to define it’s configuration, resources and environment to integrate with the provisioning tooling in place should be defined. The configuration should be pluggable (e.g. from a database, an external file,…) and the configuration should also be changeable at runtime.

Also there should be a standardized way to evaluate a configuration for an already deployed application.

→ EE deployments must be configurable. Configuration must be controllable from external sources, which are not controlled by the EE container.
→ External resource can override all aspects, or only override/extend specific parts, but still consider configuration data deployed with the application.
→ a contract is required, how this external configuration can be included/provided.
→ a contract is required, how according configuration is modelled, so the external source can "implement" the contract.
→ Configuration may be fully or partially mutable.
→ Changes on configuration must be observable.
→ a service is required that allows to read out the configuration of a deployed application.

Injectable Configuration and Fragments

As a developper I want to be able to configure my application/module something like this :
public MyPojo {
  private String currency;
  private Long currencyRate;

  // complex algorithm based on the currency

How do I configure that depending if my app is dealing with dollars or euros ? The DeltaSpike way of doing is something like :

public MyPojo {
  @Inject @Config("myCurrency")
  private String currency;
  @Inject @Config("myCurrencyRate")
  private Long currencyRate;

  // complex algorithm based on the currency

The Seam Config way of doing is quite clever. They use a namespace that is relative to the packing. So, without changing the initial code (so, forget about the @Inject above) they have an XML file that is able to override each attribute of any file.
As a Java EE user (developer or devops) I would like also to be able to package different versions of deployment descriptor fragments within my Java EE application archive, and be able to select which one is used via a -D command line argument.
E.g. have the following file structure within the application archive (a .war in this case):


And then either directly be able to say that conf/dev/web-fragment.xml should be used, or do this indirectly via an include directive and a placeholder in the main deployment descriptor for this type of fragment (in this case web.xml):


→ Application Configuration must be supported.
→ Configuration must be injectable using CDI
→ Configuration should support fragements, which can dynamically loaded by properties on the current runtime environment, or other mechanisms.

Scenario Testing

When testing a Java EE solution, it must be possible to easily control the configuration provided, so isolated component tests can be written effectively. Also it should be possible to control/isolate the configuration level for each test case.

→ isolation of configuration services
→ API for controlling the configuration provided, required for according implementations in the testing frameworks.

Scenario Modules

Complex applications are often built out of many more fine granular pieces, often called modules or plugins. This could be technical abstractions, business models, products or UI components. All of them require some configuration, which may be different for different runtime deployments (e.g. product customizations).

→ it must be possible to add configuration that exceeds the EE deployment aspects (Application Configuration).
→ this configuration must be deployable in different ways, along the code, or from external sources.

Scenario Staging

Different companies go through different staging levels during the development of software components. Currently only rarely the EE frameworks support staging aspects, nevertheless no broader, well modelled staging concept is defined. 
Different companies also have different staging or sub-staging levels in place, which also must be reflected. Especially with sub-stages inheritance of stage related configuration is common sense and should be supported.

→ Main stages available and to be supported by Java EE must be defined.
→ Enable sub-stages, additional aspects to be added, so also custom stages can be supported by configuration.
→ Allow stage properties inheritance, where needed.

Custom of the Shelf (COTS) Integration

When buying software from an external software company it is often very cumbersome to integrate, adapt and customize third party software to the internal operational requirements. Especially, when software is delivered as ear modules portability is often very difficult and time consuming. Configuration should enable COTS providers to define a customization contract, which also can be part of the COTS software interface and integration specifications. This would allow operations to better control and configure third party solutions as possible, whereas in the evaluation phase the integration and configuration options can explicitly be defined.

→ It must be possible to document configuration aspects supported.
→ It must be possible to configure arbitrary aspects, with basically arbitrary complexity, exceeding what is defined by Java EE.
→ Configuration must be overridable from external sources (the operations which must operate the COTS solution).

When operating huge server farms targeting Java EE solutions a typical process is as follows:
  1. An order for a Java EE deployment is created.
  2. An according logical domain is created and prepared image with a standard setup is installed.
  3. The logical domain and the containing Java EE application server are started in standalone mode.
  4. The application(s) are copied to the server and automatically deployed.
Hereby it would ease life of administrators, if deployment of EE solutions can be controlled/automated by the application server. This requires that the application server can be startup in some "maintenance mode", which allows to trigger its configuration service, so according deployments can be controlled by some (external) deployment controller.

→ Configuration must be injectable/deployable also into a running application server.
→ It must be possible to listen to configuration changes, so the deployment could be controlled similarly based on configuration changes (events).
→ configuration must be mutable and changes observable.               

Some Conclusions

So taking all into account, I would suggest the following:

  • Configuration is a very complex thing (OK, this is not new).
  • Configuration is dependent on the environment.
  • Configuration can be static and/or dynamic.
  • Configuration can come in different flavors and types.
  • Different companies have different sources and external systems in place, where and how they manage configurations. It must be possible to interoperate with all/most of them.
  • If EE Configuration focuses only on Java EE aspects, it will fail to cover some of the most important use cases and will make Java EE to fall back much behind e.g. what Springsource or other Cloud platforms are offering already as of today.
  • Configuration should leverage existing functionalities, e.g. by being injectable into CDI, instead of reinventing the wheel.
The good news is that, if interpreting configuration as a more broader and generic concept all/most of these aspects can be covered quite well with only a few abstractions. Though having said that, I am not sure, what will be covered at the end. Nevertheless the benefits for application programmers in Java EE would be tremendous, even if only a few aspects will be targeted. 
One of the risks I currently see, is that configuration aspects are targeted in a too narrow sense, focusing on leveraging EE as a platform only, because
  • focusing on EE only may not require to model configuration in a generic way, which may reduce the flexibility achieved at the end. Especially it might constrain the interoperability of configuration per se or, even worse, it might lead to two different ways of configuration in the future: one for application logic, one for EE logic.
  • adding configuration to all the existing JSRs is a huge and tremendous effort. To try to drive (remodel?) all required changes out of one JSR may quite probably make it fail. Nevertheless, focusing on the most important EE aspects, like EJBs, CDI, servlets, JSF, JMS, JPA, would still create huge benefits, but leave enough time for other aspects described above.
As always, you can add your comments or, even better, add your use cases, you want to be solved, so we can ensure we have covered the most important ones here...

1 comment:

  1. When you write the scenarios doesn't it automatically select instances from the JSEE IDE. I use net beans and it does that for me pretty easier than creating use case scenarios at once.