OpenLiberty server.xml boolean variable data-types - websphere-liberty

OpenLiberty does not seem to support variable substitution of boolean data-types. I have a MicroProfile JWT configuration element (ignoreApplicationAuthMethod) that I would like to tokenize. Are there best practices for externalizing boolean parameters needed in server.xml? To work around this I have pulled the entire mpJwt configuration element up into our parent environment specific xml, but this in not ideal as not every server requires this mpJwt configuration.
What I would like to do:
`<mpJwt audiences="myAud" id="${jwtBuilderName}" ignoreApplicationAuthMethod="${enforceJwt}" issuer="http://openliberty.io" keyName="secretKey" mapToUserRegistry="false"/>`

Related

How to retrieve full endpoint URL in Quarkus test?

I am looking a solution to retrieve full endpoint URLs within Quarkus application to use it in tests to avoid hard-coding the paths.
The official guide suggests using the #TestHTTPEndpoint and #TestHTTPResource annotations.
If I annotate my test class with #TestHTTPEndpoint(MyResource::class), then all calls via RestAssured without specifying the path work just fine. The problem is, when I try to retrieve the endpoint URL like this (let's say, I need to call multiple endpoints in one test):
#TestHTTPEndpoint(MyResource::class)
#TestHTTPResource
lateinit var myResourceUrl: URL
it kind of works, but the injected URL does not include the quarkus.http.root-path value.
Instead of http://localhost:8081/root-path/my-resource I get just http://localhost:8081/my-resource.
Is there a way to retrieve a full endpoint path that includes the quarkus.http.root-path value?
Introduction
Let's consider the following versions as the current versions.
Quarkus: 2.11.2.Final.
Root cause analysis
The io.quarkus.test.common.http.TestHTTPResourceManager (TestHTTPResourceManager for short) class performs the value injection into the fields annotated with the io.quarkus.test.common.http.TestHTTPEndpoint (TestHTTPEndpoint for short) annotation:
The TestHTTPResourceManager class retrieves an instance of the org.eclipse.microprofile.config.Config (Config for short) from the org.eclipse.microprofile.config.ConfigProvider (ConfigProvider for short) class and uses the test.url configuration property value retrieved from the Config instance (the Config.getValue(…) method call) as the base URL.
The retrieved test.url configuration property value seems to correspond to the test.url system property value that was provided by the io.quarkus.test.common.http.TestHTTPConfigSourceProvider (TestHTTPConfigSourceProvider for short) class.
Possible root cause
For some reason the TestHTTPConfigSourceProvider class does not take into account the quarkus.http.root-path property value, when providing the test.url system property value, which seems to be used as the base URL: quarkus/TestHTTPConfigSourceProvider.java at 2.11.2.Final · quarkusio/quarkus:
static final String TEST_URL_VALUE = "http://${quarkus.http.host:localhost}:${quarkus.http.test-port:8081}${quarkus.servlet.context-path:}";
static final String TEST_URL_KEY = "test.url";
Therefore, it looks like a Quarkus issue: a defect (a bug) or a lack of a feature (or a lack of the feature implementation).
Therefore, it is worth reporting it as a Quarkus issue.
OK, so it seems to be a bug in Quarkus and will be fixed soon.
#TestHTTPResource annotation injects endpoint URL without the quarkus.http.root-path segment · Issue #27416 · quarkusio/quarkus · GitHub.
As a workaround, one could set the quarkus.servlet.context-path property in the test/resources/application.properties file like this:
quarkus.servlet.context-path=${quarkus.http.root-path}

Sharing properties between bootstrap configurations

Problem:
I have two libraries whose purpose is to take properties from their respective sources and provide them to my application at startup. Currently both libraries provide their own PropertySourceLocators as a part of their BootstrapConfiguration.
(Just as described here https://cloud.spring.io/spring-cloud-static/spring-cloud-commons/1.3.3.RELEASE/multi/multi__spring_cloud_context_application_context_services.html#customizing-bootstrap-property-sources)
E.g.
libraryX is responsible for getting properties from SourceX and configuring a respective PropertySourceLocator.
libraryY is responsible for getting properties from SourceY and configuring a respective PropertySourceLocator
These libraries are configured at my bootstrap.yaml. E.g.
libX.enabled: true
libX.password: ${LIB_X_PASS}
libY.enabled: true
libY.password: ${LIB_Y_PASS}
Everything works great as long as these libraries don't use properties from one another.
Unfortunately, in my case libX should be a source of ${LIB_Y_PASS}.
So the bootstrap.yaml is now looking something like this:
libX.enabled: true
libX.password: ${LIB_X_PASS}
libY.enabled: true
libY.password: ${libX.values.lib_y_pass}
In this configuration application no longer starts since resolution of ${LIB_X_PASS} and ${libX.values.lib_y_pass} happens before PropertySourceLocators are called.
Potential solutions:
Use #PropertySource instead of PropertySourceLocator at libX.
Values provided by #PropertySources seem to be available at the moment when resolution of properties in bootstrap.yaml is happening. The only issue is, is that it seems to have the same priority with other application*.yaml/application*.properties files, located in the project. So it is impossible to override existing properties with something that will come from libX.
E.g.
libX.enabled: true
libX.password: ${LIB_X_PASS}
libY.enabled: true
libY.password: ${libX.values.lib_y_pass}
libX.values.lib_y_pass: dummy_password
libY.password will have dummy_password value instead of whatever comes from libX #PropertySource. Possible reason for that is the fact that bootstrap.yaml as propertySource comes before the property source libX created and during resolution spring picks the value from the first propertySource that has it.
Use org.springframework.boot.env.EnvironmentPostProcessor
We can inject libX property source as first property source during environment post processing phase.
E.g.
#Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
....
environment.getPropertySources().addFirst(libxPropertySource);
}
This seems to work fine and fixes the problem from the solution#1, but I don't know if there are hidden problems that I haven't found yet.
Question
Are there better ways to approach the problem?
It seems like either:
A) My case (when I need properties from one bootstrap PropertySourceLocator in another) goes against the design of PropertySourceLocator and in this case hacks like these is the only way.
B) I'm missing something and the problem can be solved in an much easier way.

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

Setting spring.profiles.active to value with variables in application.properties

Is it possible to set spring.profiles.active in application.properties to a value containing other variables? Apparently, I cannot get this to work.
Here is what I want:
one=${APP_ONE:foo}
two=${APP_TWO:bar}
spring.profiles.active=${one},${two}
Here, also the environment variables APP_ONE and APP_TWO should be interpreted and end up in spring.profiles.active.
I then want to be able to refer to this in applicationContext.xml in a <beans profile="one"> tag.
Sorry, if I'm not clear enough here but I do not know how to be more precise.
It is possible. However you cannot define the variable for spring.profiles.active in the same(or lower precedence) of the property source order in which spring checks. The order is mentioned here.
In your case, you have tried to interpolate the variables "within" the same property source. You can do it for other properties but not for spring.profiles.active, because it is probably picked up first to enable spring to decide what other profile specific properties needs to be checked.
If you change your application.properties to
spring.profiles.active=${APP_ONE:foo},${APP_TWO:bar}
and then set the APP_ONE,APP_TWO variable with a higher property source order (for example command line arguments). It should set the profiles as expected.
I did not understand the second part of your question, but if you want to know what profiles are active, programmatically, you can simply autowire Environment and call the corresponding methods.
#Autowired
Environment env;
Environment has methods like
String[] getActiveProfiles()
String[] getDefaultProfiles() //and
boolean acceptsProfiles(String... profiles)

Terracotta - Cannot cast to com.tc.object.bytecode.TransparentAccess

I have a rather large spring application, and all I'm trying to share is a single Map (using util.ConcurrentMap as implementation).
To do this, I created a bean in my appContext, and I tried to use the following tc-config line:
*/applicationContext.xml
Must I do something else to enable this to work? MyClass is a rather simple domain object that contains only primitives, two constructors, and accessors/mutators.
Must I do something else to get this working? I'm using Terracotta 3.0.0.
You need to create a tc-config.xml config file as described in http://www.terracotta.org/web/display/orgsite/Spring+Integration.

Resources