How to exclude multiple Spring profiles in Kotlin? - spring

I used this construction:
#Profile("!test")
Okay, but I need to set do not use this bean with multiple profiles. Insofar as value field is String[], I wrote this:
#Profile(value = ["!local", "!test"])
and get this exception:
Caused by:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'ru.example.service.AuthenticationService'
available: expected single matching bean but found 2:
testAuthenticationService,springAuthenticationService
As we see, the construction above not works. How to set profile in my case?

#Profile(value = ["!local", "!test"]) is the equivalent of `#Profile("!local | !test") meaning that only beans that are BOTH local and test are excluded.
What you need is `#Profile("!local & !test") to exclude either local or test.
This is an example of De Morgan's Law where !(foo | bar) == !foo & !bar, but you had !foo | !bar == !(foo & bar).

It works, but it is telling you that by having those two active profiles you have to beans of type AuthenticationService when only one is expected.
This is what you need to fix. #Profile with multiple profiles is working just fine.

Related

Quarkus ConfigMapping: how to map properties with keys with and without next level at the same time, like "fields" and "fields.excludes"

Converting my app to use Quarkus #ConfigMapping is not easy, especially when the properties names may be used by other apps and you are not free to change them.
I have two keys like fields(set of string) and fields.excludes(another set of string). I want to know what I can do to map both of them. I tried:
Set<String> fields();
#WithName("fields")
FieldsExcludes fieldsToExclude();
interface FieldsExcludes {
Set<String> excludes();
}
...
No compilation error, but runtime error:
Caused by: java.util.NoSuchElementException: SRCFG00014: The config property app.operator.0000001.endpoint.0.fields.exclude is required but it could not be found in any config source
at io.smallrye.config.SmallRyeConfig.getIndexedValues(SmallRyeConfig.java:114)
at io.smallrye.config.SmallRyeConfig.getValues(SmallRyeConfig.java:106)
...
Of course, I think Quarkus cannot tell if "fields" is a field of set, or a field of type FieldsExcludes. But this kind of configs are valid in YAML.
fields: [a,b,c,d]
fields.exclude: [e]
(if I break line at 2nd line after fields it's not valid; but if I put it like this it's valid, at least for Intellij IDEA)
See here: https://quarkus.io/guides/config-yaml#configuration-key-conflicts, in the doc it's stated that it's valid; I can use a ~ as a null key. So fields as a list and fields.exclude as another object should be supported.
OK at last it seems already supported; the error is due to it's not defined as "Optional<>" so Quarkus can find it in one place but cannot in another. (YAML contains 2 ConfigDetail, one of them does not have excludes, and it has no default value)
The final code is like this:
interface ConfigDetail {
Set<String> fields();
#WithName("fields")
Optional<FieldsToExclude> fieldsToExclude();
}
...
interface FieldsToExclude {
Set<String> exclude();
}
fields:
~: [a,b,c,d]
exclude: [e]
...
fields:
~: [a,b,c,d,e]
...

SpringBoot property value inside annotation

I have this annotation
#Listener(topics = "test")
that I want to relace with
#Listener(topics = "#Value(\"${topics}\")")
but I have this error
Could not resolve placeholder 'topics' in value "#Value("${topics}")"
Try:
#Listener(topics = "${topics}")
and make sure the property actually exists.
(Not a 100% sure that it works, but somewhat confident ;) )

#Value is not working for class that implements Condition as expected

I have class that implements Spring Condition here.
when I run the main app it prints the below output in console.
host = null
port = 0
${userstore.host} localhost
${userstore.port} 3000
returns true
The host and port which are annotated with #Value("${userstore.host}") and #Value("${userstore.port}") are null and 0 respectively but when I print System.out.println("${userstore.host} " + System.getProperty("userstore.host")) and System.out.println("${userstore.port} " + System.getProperty("userstore.port")) it prints the configured value correctly.
I've tried #Value("#{systemProperties['userstore.host']}") as well but no success.
what is the mistake that I'm doing?
I have checked the class in your git repository. The Problem is the Class implementing Conditioninterface. The Spring container doesnt consider the class object as bean, so it doesnt perform autowiring and any #Value processing on the same instance. That is the reason your #Value fields are getting null values.
you can get the values from ConditionContext something like below:
conditionContext.getEnvironment().getProperty("userstore.host");
conditionContext.getEnvironment().getProperty("userstore.port");
or you can fetch the values using java.lang.Systemclass as mentioned in your code.

How do you define propertychain in owlready

Recently, I started to study owlready, and faced with much problem.
I defined a PropertyChain as follows.
class friend(Person >> Person, SymmetricProperty):
pass
class potentialFriend(Person >> Person):
# potentialFriend := friend o friend
equivalent_to = PropertyChain([friend, friend])
I tried to get person.potentialFriend.indirect(), but failed. I read the source codes, since the doc on web is too simple, and found that PropertyChain works like a list, I thought it returned a Property. How do I compliment what I want?
How do you use PropertyChain? Is there some concrete examples.
PS: The source codes(.py files) indent with only two whitespaces, :o!
You can use:
P.property_chain.append(PropertyChain([P1, P2]))
...where P1 and P2 are already created ObjectProperties. In your case, P is potentialFriend. P1 and P2 are both friend.
For the reasoner to infer the property chain, don't forget to set its parameter infer_property_values to True :
sync_reasoner(infer_property_values = True)
After that, the reasoner manages to infer the property and you can get it with person.potentialFriend.indirect().

Spring boot - #ConditionalOnProperty or #ConditionalOnExpression

I'm using Spring-Boot-1.1.7.
My intention is to add a bean to my context according to a value of a property of type string.
I mean, I can see a lot of examples of boolean values such as this:
#ConditionalOnExpression("${xxx.enabled:true}")
But I want an expression based on a value of a property, for example:
#ConditionalOnExpression("${server.host==localhost} or ${server.port==8080} ")
or something like that.
Can someone show me an example how to do it?
Eventually , this one worked for me:
#ConditionalOnExpression("'${server.host}'=='localhost'")
For property value conditional I used:
#ConditionalOnProperty(name="server.host", havingValue="localhost")
If the value you want to compare with is a literal, you need to quote it, and the placeholder would go round the property name (not the whole expression), e.g. ${server.host}=='localhost'
If you are using e.g. a string value and want to check if a value is set, you can use a simple "check":
#Component
#ConditionalOnProperty(value = "foo.value")
public class Foo {
private String value;
// getter/ setter and other stuff ...
}
If you add: foo.value: bar to your application.yml file the component will be found and added to the application context, but if you do not set a value the component will not be added.
If you want to check if the component is found, you can use: debug: true in your application.yml.
Foo matched:
- #ConditionalOnProperty (foo.value) matched (OnPropertyCondition)
vs
Foo: Did not match:
- #ConditionalOnProperty (foo.value) did not find property 'foo.value' (OnPropertyCondition)

Resources