I have Tomcat Virgo Server. I am deploying couple of OSGi bundles. I want to expose settings through properties, so the service within bundle can read it though Java System.getProperty(String) API. Is it possible ?
You should use OSGis ConfigurationAdmin for doing this. You can deploy your properties files into [VIRGO_HOME]/pickup and then consume the properties from ConfigurationAdmin Service over the configurations pid. Virgo recognizes your properties files in its pickup folder and automatically exposes them over the ConfigurationAdmin Service. You could also list your properties files in a plan file if you use plans to deploy your bundles as an application.
Please refer to the official documentation on the Virgo Documentation Page [1] for further details.
And if you are using Spring/Blueprint you can stick to the property placeholder as you are used to. Just use the osgix namespace handlers and do something like this:
<osgix:cm-properties id="cmProps" persistent-id="com.xyz.myapp">
<prop key="host">localhost</prop>
</osgix:cm-properties>
As by default the persistent-id or pid is the name of your properties file. For further reference have a look at Gemini Blueprint Documentation as well [2].
[1] http://www.eclipse.org/virgo/documentation/virgo-documentation-3.6.4.RELEASE/docs/virgo-programmer-guide/htmlsingle/virgo-programmer-guide.html#developing-applications-configuration-artifacts
[2] http://www.eclipse.org/gemini/blueprint/documentation/reference/1.0.2.RELEASE/html/compendium.html#compendium:cm
Related
When developing a spring based web app (and deploying to tomcat), we can put our configuration in several places. One of them is catalina.properties. I would like to know how catalina.properties file is made available to spring app. Is it tomcat who does this or spring who loads catalina.properties file? How spring knows from where to load configurations.
Tomcat automatically makes any properties configured in catalina.properties available as system properties. Spring's Environment uses a number of different sources for the properties that it contains. One of those sources is the JVM's system properties. As a result, the properties specified in catalina.properties are available via Spring's Environment.
In Spring Cloud Zuul server we can define all routes which need be redirected via "application.properties".
For example:
zuul.routes.resource.path=/api/**
zuul.routes.resource.url=http://api.com:9025
Once the fat jar is created the "application.properties" is encapsulated into jar, and it's not possible to edit and reload the rules inside the file.
Is there any to inform Zuul about the routes in an external file, and at the same time reload them without stopping the server?
You can use spring cloud config for that.
Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_spring_cloud_config_client
...a bit late to the party, but...
You can do all that you want with the ConfigServer!
Create an application.yml for config that is common across ALL applications
Create profile specific application-mycommonprofile.yml. As 1. but for the 'mycommonprofile' profile.
Create an appX.yml for each application that is specific to that application.
Create profile specific appX-myprofile.yml. As 3. but for the 'myprofile' profile.
All of these files are optional and are not dependent on any others. You can have an application-mycommonprofile.yml without an application.yml for example.
Hope that helps!
Another late-to-the-party answer, but another way is to use a profile config file, which lives in the filesystem, outside the fatjar.
If the configuration name of your Zuul proxy is 'zuul' and your normal config file is 'zuul.properties' or 'zuul.yaml', then it looks for a profile-specific config file in 'zuul-.properties' or 'zuul-.yaml'.
If you do not specify a profile, then the profile named 'default' is active.
So you can load properties from an external file name 'zuul-default.properties' or 'zuul-default.yaml' (or 'zuul-default.yml', if you use a 3-letter filename extension).
This will then be loaded when no other profile is specified.
I have a custom jar with a custom Main class, which starts the OSGi Framework and installs/starts the bundles. This main jar also includes a properties file.
Goal: I have a bundle A which should pick up the properties of this properties file of the main jar somehow.
My first attempt was to define a component in bundle A (using Apache Felix SCR/ Declarative Services) and retrieve the properties in its activate-method. This works so far that I'm getting the default value specified in the #Property-annotation.
But how can I now pass the properties of the properties file to this component?
Passing arguments to OSGi application
mentions to use the Config Admin, but how can I use this in the Main class?
The Config Admin is in a bundle, not in the main jar, and the bundles are not installed in any specific order
The Main class doesn't know anything about the bundles it installs, let alone a specific service.pid.
Update:
I'm trying now an approach suggested by #vizier (which doesn't use Config Admin and thus doesn't have the mentioned issues):
define a service interface in the main jar (system bundle)
provide an implementation, which reads the property file (the properties file is in the same jar)
export the package X containing this service interface
bundle A then can import the package X and e.g. reference the service using Declarative Services
But in my bundle A I'm getting:
org.osgi.framework.BundleException: Unresolved constraint in bundle <bundle A> [14]: Unable to resolve 14.0: missing requirement [14.0] osgi.wiring.package; (&(osgi.wiring.package=<package X>)(version>=0.1.0)(!(version>=1.0.0)))
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3826)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1868)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295)
at java.lang.Thread.run(Thread.java:722)
Does the system bundle only export osgi packages even if some custom packages were added to Export-Package in the Manifest file? Or what is going wrong?
As always, register a service ... The receive bundle (and any other bundle) can search for the service and read the properties. Since you're the framework launcher you can register any service you want through the Framework object you get from the Launching API.
In bnd(tools) I have a launcher. It uses the OSGi Launcher API to create the bundle, similar to what you describe. I pass the command line arguments as properties on a Launcher service. Look at https://github.com/bndtools/bnd/blob/master/biz.aQute.launcher/src/aQute/launcher/Launcher.java for an example.
You can of course also just get the Configuration Admin service through the Framework object and use it to register Configurations. It is quite easy (just actually done it) to define the configurations in JSON (or, dare I say it, XML) file and then read it and update Configuration Admin.
You can make the jar containing the main class an OSGi bundle as well, and during startup you install this bundle together with the other bundles. Then you can let other bundles access the properties contained in your jar using a number of techniques, such as the followings:
provide a class for accessing the properties and integrate using module dependancy (Export-package/Import-package)
provide as service for accessing the properties
use Config Admin
The simplest may be to make the jar with the properties file a fragment, with bundle A as the host.
Then the properties will be on the classpath of the bundle and can be easily read.
We have a similar case in Apache Karaf. There we simply set the properties as java System properties and also give them to the framework. These are then available as properties in the OSGi bundle context. So this is nice for properties that are for the whole platform. See the project of the karaf starter: http://svn.apache.org/viewvc/karaf/trunk/main/
If you need properties in user bundles then using the config admin service is much nicer. It decouples the user bundle form the mechanism of retrieving the properties and also allows updates at runtime. There is a also the metatype service which allows to define the structure and meaning of the properties which allows nice forms for editing the properties.
I describe in two tutorials on my website how to use the config admin service:
Config Admin Service: http://www.liquid-reality.de/x/G4Be
Metatype Service: http://www.liquid-reality.de/x/KoBe
I feel like an idiot, but where/how do I override the Jackrabbit configuration parameters when deployed in Glassfish v3? I've tried setting rep.home in the Glassfish Admin -> Enterprise Server -> System Properties panel, but it doesn't seem to have any affect.
Do I have the property name correct?
Is this not the right place to do
this?
BTW - I'm using the Jackrabbit release bundled with the Sling API.
The Jackrabbit Configuration Parameters indicated by your link are automatically set by the Jackrabbit Repository implementation when reading the repository.xml configuration file.
What you can do to relocate the Jackrabbit Repository inside Sling is either set the "sling.repository.home" framework property (of the OSGi framework into which Sling is deployed).
Alternatively you can edit the Repository Server configuration in the Web Console Configuration Manager page. Select the configuration labeled something like org.apache.sling.jcr.jackrabbit.server.SlingServerRepository.XXX where "xxx" looks like UUID string. In that configuration change the Repository Home path. Please note, though, that this will not move your existing repository directory but just tell Sling to use a different location.
The services defined in my jboss-esb.xml refer to properties from the SystemProperties service.
When I change a property in the properties file (ie, /conf/my-props.properties) I can reload them using the SystemProperties MBean. I am unsure, however, how to get the services to reload using the new properties without redeploying the esb archive or without deploying the archive exploded and 'touching' the jboss-esb.xml.
Is there a way that I can trigger the esb to reload the services via an MBean or something similar?
I don't know if you're already using Spring, but since probably you are, you might want to give a try to ReloadableResourceBundleMessageSource. I can give you more details about this if you find this to be a viable solution.