Is there a way to make the component scan configurable externally or through an intermediate resolver class? My requirement is that a common library should include one or more of other smaller facilities (each having their own controller, services etc.) depending on whether those are "configured" or needed - e.g. in application properties.
The closest I can see a possibility of designing this is to declare a #Configuration class in the common library and keep it in the component scan class path (always). In this class I need some way to say that the following are the allowed scan paths (based on how downstream projects have configured their application properties).
Seems like TypeFilter custom implementation should do it. But how do I read application properties from inside the type filter implementation (annotation takes only the .class, so Spring must be initializing it.
Any other ways? Thanks!
Regards,
Arnab.
This document describes how to create your own Auto-Configuration. It allows you to read properties and utilize several variations of #Conditional annotation.
Related
I have a project that uses Spring. The project consists on two different parts, the generic part and the specific one. The generic part is compiled as a .jar, it defines a set of traits and it's used as a dependency by the specific part, which is the one that implements the methods.
In order to test the generic part, I have created a "fake" implementation of one of the trait (let's say "fakeMethodA"), under the test directory of the generic project and I annotated this fake implementation with the #Component annotation. I'm getting the beans using the application context.
The problem comes when I try to use this generic part on the specific project. Since my actual implementation of this trait (let's say "methodAImplementation") also has a #Component annotation, when I run my tests I get:
org.springframework.beans.factory.NoUniqueBeanDefinitionException
expected single matching bean but found 2:
It finds the fakeMethodA from the generic part and methodAImplementation from the implementation. Is there any way to exclude this "fake" implementation from the execution? Is there a better way to define this?
Any help would be greatly appreciated.
The problem was solved by the use of #Profile annotation on the generic method.
I annotated the fake method on the tests with:
#Profile(value = Array("Test"))
And the right implementation with another profile value. After that, when I select the bean from the context, I can select the correct profile.
In OSGi R6 I desire to programmatically validate user-supplied String configuration properties plus a service factory PID against what is supported by whatever configurable #Component (or ManagedServiceFactory) that declares it configures this PID, e.g. #Component(configurationPid=some.service.factory.pid, ...). Additionally, I want to somehow convert valid String properties to their appropriate property types. Looking through the OSGi Compendium, it seems the Metatype Service is what I'm looking for.
If that's correct, given the following:
Applicable components uses component property types to specify their configuration
Component property types are annotated with #ObjectClassDefinition
Components are annotated with #Designate, mapping it to the applicable #ObjectClassDefinition
Is this the most straightfoward way to map factory PIDs to their ObjectClassDefinition:
Call BundleContext.getBundles(). For each bundle, call MetaTypeService.getMetaTypeInformation(Bundle).
For each returned MetaTypeInformation call MetaTypeInformation.getFactoryPids() and filter on the factory PIDs I care about.
For applicable MetaTypeInformation, call MetaTypeInformation.getObjectClassDefinition(String, String) to obtain the ObjectClassDefinition, using either a default or specific locale.
(Tangential, the above seems expensive to perform each time, so caching bundle IDs, mapping them to associated factory PIDs, and keeping the cache up-to-date somehow seems appropriate.)
Or, is there some other OSGi magic that can be programmatically queried with a service factory PID, which returns something that gets to some ObjectClassDefinition quicker than the above process?
Update 1
Stepping back, I'm writing a CRUD-wrapper around ConfigurationAdmin for each of my configurable components. I'm trying to avoid createFoo, deleteFoo, updateFoo, createBar, ... My application happens to be amenable to URIs. So my working approach was to use Metatype Service, pass in a parsed URI query (Map<String, List<String>>), and then utilize Metatype Service to validate and reconstruct these values, circling back to the OP. (On the side, seems like a not-pretty hack to me.)
Another approach was to use aQute.bnd.annotations.metatype.Configurable.createConfigurable(Class, Map), which I preferred more! Until I saw this bnd GitHub comment:
The bnd metatype annotations are deprecated in bnd 3.2 and will be removed in bnd 4.0. These annotations are replaced by the OSGi metatype annotations.
So I didn't want to rely on that package if it's going away soon. I looked at what Felix does and didn't want to use their equivalent Configurable class. I'm all ears on different approaches!
Update 2
Reducing this more, I'd like to validate potentially user-supplied key/values configuration properties to ensure they're applicable for some configuration pid, prior to calling ConfigurationAdmin.createFactoryConfig. Maybe this is overkill?
I once created a class that takes the configuration class, creates a proxy, and then uses this proxy to get the name of the method and the type. It was used something like this:
ConfigHelper<Config> helper = new ConfigHelper( Config.class, "my.pid");
int port = helper.get().port(); // get the configuration
helper.set( helper.get().port(), 1000);
helper.update();
The proxy you get from the get would record the method when one of the methods is called. On the set method it would use the last called proxy method to identify the property. It would then convert the given value to the property type based on the method's return value. The bnd converter is ideal for this but I think Felix now has a standard OSGi converter. (Which is based on the ideas of the bnd converter.)
The method name is then used as the property. The name mangling necessary is defined in an OSGi spec. This allows you to use underscores, Java keywords, and dotted names.
So this would allow you to roundtrip configurations. No worry about the types, they will automatically fall in their place.
Updated This is updated after I understood the question better
Updated 2 Added an example at https://github.com/aQute-os/biz.aQute.osgi.util/tree/master/biz.aQute.osgi.configuration.util
I implemented Dynamic DataSource Routing using Spring Boot (JavaConfig) to add and switch new DataSources in runtime.
I implemented AbstractRoutingDataSource and I need access to all resolvedDataSources that is a private property. How can I do it?
I actually don't know why that field has not been made protected to let implementing classes access the data sources set. Regarding your questions two options come into my mind.
Option 1:
Copy the code of AbstractRoutingDataSource into a class of your own. Then you can expose the resolvedDataSources simply by a getter. This should work as long as the configuration relies on the interface AbstractDataSource and not AbstractRoutingDataSource.
Option 2
Pick the brute force way by accessing the field via Reflection API
I would like to add extra attribute to the internal representation of beans in Spring. Is it possible? What mechanism should be applied if any?
My goal is to define my own beans for my framework. I can do it from scratch or reuse Spring mechanisms.
You could have a look at the documentation Container Extension Points.
To achieve customization you can create a:
BeanPostProcessor bean which operates on a bean instance. For example this allows to create a custom bean registry, to proxify...
BeanFactoryPostProcessor which can operate on bean metadata. This allows for overriding or adding properties even to eager-initializing beans, modifying the class...
BeanDefinitionRegistryPostProcessor which can operate right after the registry initialization. This allows to create, remove or update beans definitions.
For example you can create a new BeanDefinitionRegistryPostProcessor which will register (or modify) beans using a custom implementation of BeanDefinition which will contain custom attribute based on for example your owns annotation.
Could you elaborate a bit what are you trying to achieve with your framework?
Merci beaucoup, Nicolas :)
I will study both your answer and the documentation you provided. I have already found the *Postprocessors you mentioned but I was not sure if this is the right place and what is the nature of their customizations (subclassing or something different) and what are the consequences. My problem is not as simple as I told (not just adding an attribute) - the extended Spring bean should be used also in cooperation to Spring+AspectJ (not SpringAOP), especially with declare-parents construct. I would like to be able to create proxies for the redefined beans as well. I will let you know what are the results of my investigation and may be I will ask some questions.
And the answer to all of you:
My framework is dedicated to defining graph modeling languages (meta-models) at run-time (being far extension of OMG standards) and I am looking for solutions of limits introduced by current object representation in JVM, which promotes behaviour over structure. This is one of several approaches, but the most prospective for me due to the relatively small effort.
I've found Sling's ability to associate Servlets with certain resource types, selectors and extentions, methods really useful in component development.
Now I'm starting to look into the ComponentFilterChain & would like to create filters that only register against certain resource types, in the same way as Servlets above.
From the Example filters on the Sling project, I see that there's a pattern property that you can apply for particular paths, though it feels like this limits the benefit of having components.
Really what I'm looking for is an equivalent property to sling.servlet.resourceType that I can annotate my Filter with so that only certain components enter this filter as part of the component filter chain, rather than having to check the component resourceType/superResourceType within the Filter.
Is this possible with Sling filters? Or is there an equivalent approach that can be used?
Out of the box, there's no way to associate servlet Filters with Sling resource types. Composing OSGi services, maybe using sling:resourceType values set as service properties, should allow you to provide similar functionality.
As of Apache Sling 2.6.14, there is an option to associate Sling Filters with resource types.
The property you need to add to your OSGi service to achieve this is sling.filter.resourceTypes.
There's a set of annotations available that make the job easier.
From the Sling Documentation
//...
import org.apache.sling.servlets.annotations.SlingServletFilter;
import org.apache.sling.servlets.annotations.SlingServletFilterScope;
import org.osgi.service.component.annotations.Component;
#Component
#SlingServletFilter(scope = {SlingServletFilterScope.REQUEST},
suffix_pattern = "/suffix/foo",
resourceTypes = {"foo/bar"},
pattern = "/content/.*",
extensions = {"txt","json"},
selectors = {"foo","bar"},
methods = {"GET","HEAD"})
public class FooBarFilter implements Filter {
// ... implementation
}