Spring Webflux Codec: Can a custom codec be added the the list of default codecs globally? - spring

I've been shown how to add custom Codecs to webflux:inbound-gateway and webflux:outbound-gateway declarations using respectively the codec-configurer and web-client attributes. How to add HttpMessageWriter<> to webflux outbound-gateway
Is there a way (and perhaps even a simple way) of adding one's custom codec to the list of default codecs and hence avoid having to declare these in the endpoints?

See CodecConfigurerFactory. You can use a CodecConfigurer.properties file to specify your custom strategies for those codecs:
# Default CodecConfigurer implementation classes for static Client/ServerCodecConfigurer.create() calls.
# Not meant to be customized by application developers; simply instantiate custom impl classes instead.
org.springframework.http.codec.ClientCodecConfigurer=org.springframework.http.codec.support.DefaultClientCodecConfigurer
org.springframework.http.codec.ServerCodecConfigurer=org.springframework.http.codec.support.DefaultServerCodecConfigurer

Related

How to map service factory PIDs to their `ObjectClassDefinition`

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

Configurable Component Scan

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.

Can i access request parameter in jackson BeanSerializerModifier?

I am using Jersey to implement rest api and Jackson to provide JSON support. I am trying to remove certain properties before serialization by overriding BeanSerializerModifier.changeProperties method.
But removing properties will be based on query parameter. Is there any way to access the query parameter in my implementation?
Use of BeanSerializerModifier itself would get complicated as the method is only called once when construction necessarily JsonSerializer for the first time. As to passing query parameters, you could pass them using contextual attributes and ObjectWriter (constructed from ObjectMapper), but that means taking over quite a bit of serialization automation from Jersey.
There is one mechanism that could be helpful in modifying serialization aspects without taking over the whole process: registering ObjectWriterModifier, using ObjectWriterInjector. These are part of Jackson JAX-RS provider, added in Jackson 2.3. Without knowing more details I don't know how easy this would be; part of the issue is that query parameters are more of an input side things, so there is no direct access to them from output processing side.

Using a custom ObjectMapper for Spring XD Json to Java Conversion

Is there an easy way to convert a JSON payload to a Java object using a custom ObjectMapper (Jackson) or do I have to provide a custom type converter. I know that I could use a processor, but somehow it would be nice to use input and output types of the stream definition.
In the second case: Am I even able to provide a custom type converter for application/json to Java?
The documentation states: "The customMessageConverters are added after the standard converters in the order defined. So it is generally easier to add converters for new media types than to replace existing converters."
I bet that there is an existing "application/json" converter - but at a first glance I could not find further information if it is even possible to replace existing converters.
Thanks!
Peter
If you look at streams.xml You can see the relevant configuration. The configured lists are used to construct a CompositeMessageConverter which visits every MessageConverter in list order until it finds one that can do the conversion and returns a non-null result. A CompositeConverter instance is created for each module instance that is configured for conversion (i.e., defines an inputType or outputType value) by filtering the list of candidate message converters, which all inherit AbstractFromMessageConverter. The list is paired down to those which respond true to public boolean supportsTargetMimeType(MimeType mimeType) (where mimeType is the value of the input/outputType). The CompositeMessageConverter is injected into the corresponding MessageChannel and converts the payload.
There are a couple of things you can do. You can override the xd.messageConverters bean definition. For example, you can replace JsonToPojoMessageConverter and PojoToJsonMessageConverter with your own subclasses. You can also insert your own implementations in the list before the above converters and have your implementation match only specific domain objects for which you need a custom JSON mapper.
Another possibility is to define your own mime type and provide converters for that mime type as customMessageConverters. In any case, follow these guidelines forextending Spring XD

Does Sling allow Component Filters configured to target only certain resource types?

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
}

Resources