Why must database name be specified in AbstractMongoClientConfiguration? - spring-boot

In https://github.com/spring-projects/spring-data-mongodb it specifies that AbstractMongoClientConfiguration implement String getDatabaseName(). Furthermore, this implementation is mandatory. I found this inconvenient to have to manage the database name property in the implementation when all I want to do is override something else (e.g. configureConverters()). Is there a reason getDatabaseName() could not have a default implementation in AbstractMongoClientConfiguration where the MongoProperties could be injected and used to derive the database name? I considered raising an issue on github, but noticed there's no "Issues" tab, so asking here.

Related

Quarkus - #ConfigMapping: built-in way to show all properties like "toString()", instead of manual building

As #ConfigMapping uses interfaces, there are no ways to implement toString(); I cannot view all values and nested values without a lot of manual work(reflection and switch case to deal with each type).
Any plan to support easy view of all levels of properties? Like a super class to inherit which handles this manual toString() like building?
In SmallRye config doc page I read this:
ToString#
If the config mapping contains a toString method declaration, the config mapping instance will include a proper implementation of the toString method.
But I added #Override String toString(); method everywhere, Quarkus just complains about cannot find property "to_string".
OK I found this issue which is implemented in this commit, which exactly adds the sentence I read into the doc; but still not very clear to me.
Adding a String toString() method in your #ConfigMapping will generate the expected toString() implementation.
This is only available starting from SmallRye Config 2.11.0 and Quarkus 2.12.0.Final, which came out just a few weeks ago. Previous versions will just try to resolve the method as a configuration property. From your description, it seems that is the case, so you may be using an older Quarkus version that does not support this feature yet.

Spring Cache+Redis cache doesn't calculate keys based on method/class names

I'm using redisson with a jcache abstraction, simply put I have this:
public class MyService{
#Cacheable("cacheA")
public String returnSomethingAfterLongTime(String parameter){
//...
}
#Cacheable("cacheA")
public String returnSomethingElse(String parameter){
}
}
Problem is that both of them create a redis key like "cacheA::parameter", in other words the class and method name are not taken into account.
This causes a problem if the string "parameter" is a common word because I have to be aware of every part of code where "cacheA" is used so to make sure that no inefficiency is brought up due to the fact that the "parameter" key could be replicated among calls.
Is there something that I'm doing wrong?
It looks like you can specify a "key" attribute to customize it to cache based on method name.
Spring Cacheable key attribute
There are a lot of good examples and answers on this post.
I've never personally used Spring Cache, but it looks like you can specify #Cacheable("cacheA", key="#parameter") and the value of parameter will be used as the key rather than the word "parameter".

Spring Ldap - multipe base names

I am trying to use spring LDAP /ODM to receive some attributes from LDAP. Is there a way to configure multiple base names in
<ldap:context-source
url="${ldap.url}"
base="${ldap.base}" // here ..is there a prop that will take an array of base names
username="${userdn}"
password="${password}" />
<ldap:ldap-template id="ldapTemplate" />
or in
#Entry(objectClasses = { "person"} base={..CAN I GIVE MULTIPLE BASENames here..})
public class LdapUser {
#Id
private Name dn;
//..
}
The app I am developing has users defined under one OU and internal TESTERs defined in another ou in our AD. So I am trying to see if I can use the same LDAP entry class for looking up everyone.
The ContextSource base is intended to specify the base of all operations on the ContextSource, and is typically set to the domain controller DN.
You can use ODM without specifying a base on the #Entry (or using a base DN higher up in the tree), but in that case you will typically use the #DnAttribute annotation in order to have the framework automatically build DNs for you (mainly needed when persisting entries back to LDAP).
If we assume your users are in the following structure:
dc=example,dc=com,ou=USERS
dc=example,dc=com,ou=TESTERS
Now, if you specify base dc=example,dc=com on the ContextSource you can have ODM handle this automatically as described briefly below:
#Entry(objectclasses={"person"})
public class Person {
#Id
private Name dn;
#DnAttribute(name="ou", index=0)
#Transient // Indicates that this is not an attribute on the entry
private String userType;
#Attribute(name="cn")
private String name;
// More attributes here
}
The above will handle automatic mapping of LDAP entries to and from the Person class. Now, if you want to find all persons, do:
List<Person> allPersons = ldapTemplate.findAll(Person.class);
If you want to find all testers you would do:
List<Person> testers = ldapTemplate.find(
query().base("ou=TESTERS"),
Person.class);
I am not very familiar with Spring LDAP but (IIRC) LDAP itself can only search from a single node (base). So, looking at the documentation, you might have to do a search from the organization (o=xx) with an LDAPQueryBuilder, adding conditions for the ous. See the javadocs.
No expert here, mind you.
With XML config at least, you can wire an LdapTemplate instance. One suggestion might be to make a new implementation called something like DelegatingLdapTemplate that gets injected with two regular templates (one per basename) and then delegates to them appropriately (or just calls one, then the other if the first one return 0 results), and use this in place of a normal template instance. This of course makes sense only if your use case really warrants this behavior (e.g. if you never know where to search for the user and have to check both locations). Otherwise, just make two separate beans.

Update field annotated with #Value in runtime

Let's imagine we have such a component in Spring:
#Component
public class MyComponent {
#Value("${someProperty}")
private String text;
}
If we define the property placeholder:
<context:property-placeholder location="classpath:myProps.properties"/>
And myPropos.properties contains the value for someProperty the value will be injected to the text field when the context is initialized. That's quite simple and easy.
But let's say that I have a service that enables user to change the value of the someProperty:
public void changeProp(String name, String newValue);
Is there a chance I can re-inject the newValue to text field. I mean it should be quite straight forward.. Basically it's nothing different than the after-initialization injection. I can not imagine that Spring does not have support for this? Can I fire some event or something?
I could do this on my own basically, but I wander is it maybe something there already? If not does anyone know what Spring class is in fact handling the injections at the first place? I could probably reuse the code there do perform this on my own if a solution does not exists.
I expect spring does not have a support for this, because the normal injection is done while creating the bean, but not will it is put in service.
Anyway: in this blog entry "Reloadable Application Properties with Spring 3.1, Java 7 and Google Guava", you can find the idea for an solution.
The key idea is to use a post processor to build a list of all fields with property fields. And if the properties are changed on can use this list to update the fields.

Custom ASP.Net Membership Provider and Certain Properties

Implementing a custom membership provider, there are certain properties such as MinRequiredPasswordLength that only provide a getter.
The documentation I find online illustrates that these properties are configured in web.config.
However, it's not clear to me if System.Web.Security.MembershipProvider (from which my custom provider is derived) will read the web.config settings and set appropriate values, or if my concrete subclass is responsible for that task.
Does the base class read and set the values, or am I responsible for doing that in my subclass?
I would have thought the base class would certainly have handled that, given it's meant to be read from web.config. However, checking here -- http://msdn.microsoft.com/en-us/library/system.web.security.membershipprovider.minrequiredpasswordlength.aspx -- this is how MembershipProvider declares the property:
public abstract int MinRequiredPasswordLength { get; }
So ... I guess you're responsible for that, eh?

Resources