OSGi console commands when there are multiple instances of a component - osgi

I'm using Bndtools, and I have created a component that adds OSGi console commands. I need to run multiple instances of this component (the number will be in the single digits, with each one manually configured) and I would like each instance of the component to expose its own set of commands, with its own scope. The name to use for the scope is available in the instance's configuration.
The problem is that the scope is defined using annotations, and is, of course, hard coded in the XML in OSGI-INF. I suppose I could have the component use config admin to change its own configuration, but that seems really ugly. Is there any other way to set the scope at run-time? An alternate way to do this that I'm not seeing? Any help would be appreciated.

You can use a Factory Component which allows you to create component instances on demand and specify configuration properties.

Related

Spring integration-graph: It is posible to show components within profiles or imports?

I'm used to work with a spring-context.xml with a "beans" root tag, where I write the whole app configuration. That way, I can see integration-graph from STS 3.6.4.
Now I want to divide some components of my app for testing purposes. First, I tried to separe the different components and create different componentX-spring-context.xml confiuguration files for each group of components of the system, and then import all of them from my main spring-context.xml. However, I could not see the integration-graph anymore.
Now I'm trying to divide the components creating multiple spring profiles, which I could use for testing. This is a cleaner way than working with multiple context files. But the problem is the same: I cannot see any of my component which are within some beans profile element, indeed I cannot see any component which are not directly on my "beans" root element, not even if the profile is "default". This is, only the components which are direct children of "beans" element are shown in the integration-graph. And obviously I cannot create multiple elements, since there must be only one root XML element.
Is there any way to configure STS to show components belonging to some profile?
Thank you!
Not at this time; the graph doesn't handle profiles or <import/>s.

Single instance of an object per transaction

I have a use case, that theoretically seems to me as it would be a solved problem. But i'm not able to find a sure fired implementation.
I've created a RESTful API, using Apache CXF, Spring and Hibernate
This application encompasses a standard Service-Proxy-DAO layered structure
I need to instantiate a custom logger object at my service (or pre-service) layer and initialize a bunch of parameters which will remain constant, for the most part through every call that goes through my application layers and back.
How can i, for every individual service call, initialize this logger object once, and use it across all my layers without having to instantiate it everytime. Either i inject the initialized object in every class i need or something on those lines.
I don't want to use static blocks, or pass the object in method signatures.
Is there anything that i can use as a part of the Spring, CXF or other java framework that allows me to implement this use-case.
EDIT: I would define a transaction as a single call to a web service endpoint, from invocation to response.
ThreadLocal would be an ideal candidate to solve your problem.
UPDATE:
Creating a thread local that is available in all the places where this "shared" reference is required will give all these contexts access to this resource without having to pass the reference around.
see http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/ - looks like a good explanation of how to use thread local and also deals with your problem space.

Maven 2 replace class implementation depending on profile?

I have MailTransport.java and two classes extending it: LiveMailTransport.java and TestMailTransport.java.
LiveMailTransport will really send emails while TestMailTransprot will only write them to the log for testing purpose.
Somewhere I do new MailTransport(); and I would like to replace every usage of MailTransport in my server-side code either with Live- or with TestMailTransport depending on the profile used for compiling (local, production, etc..).
(Similar to gwts "replace-with" on client side...)
How could I do that with maven?
Thanks!
What you want is a factory which accepts a system property. If the system property isn't set, create an instance of LiveMailTransport. If the property is there, create an instance of TestMailTransport.
Proposed name of property: com.pany.app.enableTestMails
Boolean.getBoolean(String) is your friend.
Now configure the surefire plugin to set the property and you're done.
That sounds like a misuse of Maven, cause this looks more like dependency injection task (guice for example) but there is no relationship with Maven.
If you're using Spring or some other dependency injection framework you could manipulate dependencies injected based on inclusion of corresponding configuration.
But if you want to do it with a plain bare bone Java application you could create multiple factories that will create corresponding instances of yoor MailTransport and place these factories into a different source folders. Then use build-helper-maven-plugin to add correspoinding source folder based on active profiles.

OSGi and Component Management

I have a dynamic application that uses OSGi to load modular functionality at runtime. OSGi bundles contain the modular functionality and the application loads the bundles when they are needed. This approach works okay, but I would like a more granular solution. The bundles contain components controlled through Declarative Services. I'd like to be able to load a bundle, and only enable the components that are needed within the bundle. I've done research in this area, but cannot find a solution that I'm satisfied with. One approach was to create a "gatekeeper" component that is always enabled in the bundle and through the ComponentContext let it call enable and disable component. It's a viable solution, but I could not figure out a way for the "gatekeeper" to "know about" the other components in the bundle without hard coding the component names as properties in the "gatekeepers" SCR xml descriptor.
What I prefer is a way to load bundles and "know about" all components within the loaded bundles. Be able to determine what bundle the components are located in and what state they are currently in (similar to the equinox console command 'ls' that lists out all components). I would like to enable and disable the components when needed.
How does the console do this and how could I do this in an application?
Update:
#Neil Bartlett: Sorry for the delay. I had to move on to something else. Now I'm back on this issue. Really would appreciate any further assistance. My application is role based. I need to enable components based on the functionality they provide. The goal is for all role based components to initially be disabled. Upon role change, a role manager polls each component for its provided functionality and determines whether to load it. Each component will broadcast what functionality it provides (through a common service interface). ScrService will not allow me to enable an initially disabled service component. Having the components initially enabled and let ScrService disable them as soon as possible during application startup does not fit my needs.
Have a look at ScrService. Bothe equinox and felix has it.
However, components can be made to load lazily, i.e. only when needed by other components/bundles; but that is perhaps not what you want.
In your service description, mark the components as enabled, but requiring configuration information provided by the Configuration Management service. you then can write a CM plugin service (can't remember the exact term) that can publish and modify the configuration of your components. Services by default are identified by their name, which by default is their implementation class name. Configuration data is passed as a map, and it can be empty. DS will make the service available as soon as the CM provides a configuration.
I have a similar issue, but for a different purpose:
- I have apache file install and configuration admin service to configure my components externally with property files.
- I needed to make sure that some components get the config from the outer file and the only way I've found so far is that I mark my components with ConfigurationPolicy.REQUIRED.
- But that way my plugin projects doesn't run in eclipse (where there are no config files).
- The component.xml also contains a default development configuration so I'm okay with that, just my component doesn't start until there is a config data avalilable with configadmin. My components ar unsatisfied this way, until someone creates a configadmin entry.
- I figured out that if I create a osgi command line extender that sends empty configurations to service pid's they would start up with default values in component.xml files.
- I just came here to find a way to list all bundles
But I think this solution I use can also work with your setup and that's why I write this.
Just mark all your components with the configurtationpolicy.require and you can selectively start and stop them with adding and removing configurations with configadmin. This could be hard if you already use the configadmin for other purposes too, but it may be managable as a last resort.

Spring: two database configurations online/offline

Is there a method to have two configurations that automatically use one when online and another when local?
I mean two connections saved, one for the online version (when I try my website on another server) and one for my local tests...
Sorry for my bad english, I hope that someone can understand what i mean
Yes it is possible,
I assume that your database beans are defined in a spring context file.
You have 2 choices:
You can either put the online and offline beans in separate contexts and load them depending upon an environment variable
Or you can simply pass the context files as parameters to your application and fire up spring manually

Resources