How to override applicationContext.getId() with spring boot 2.0? - spring

We have recently upgraded to spring boot 2.0 and noticed that the application context IDs aren't unique any more. Previously, if we set spring.application.index, ContextIdApplicationContextInitializer would use that to construct the application context id. I now see that in spring 2.0, the implementation was significantly changed. How best should id be set? The goal is to include the hostname as part of the id to keep systems distinct. The spring cloud docs still refer to the old way: Service ID Must Be Unique.
UPDATE
What used to happen is that spring.application.name was set in the source code of the project (ie my-app) and spring.application.index would be set in the runtime (ie, 1e4f630be), then applicationContext.id would have the value of my-app-1e4f630be. Now, it always has the value of my-app-1. The implemenation of ContextIdApplicationContextInitializer no longer references spring.application.index. This is a significant change between versions and I haven't found examples or documentation on how to customize the id properly with spring boot 2.0

Related

Why spring.jpa.properties. prefix is not always required in Spring Boot properties

I learning Spring boot and found that in some examples use the same properties with the prefix spring.jpa.properties while other do it without prefix.
For instance:
The article explains second level cahche https://www.baeldung.com/hibernate-second-level-cache and autor shows example of needed properties ( example on autor's gitHub):
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
But it did not work for me, and I spent few hours loking for the reason, but then i noticed, someone use prefix spring.jpa.properties. to get it working (Exact moment from video lesson):
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
Which perfectly worked for me.
So my questions are:
why are they working in different way?
how to understand which properties in which cases requires this prefix?
is it probably something related to my project settings OR Spring Boot version?
any other suggestions are appreciated :)
Thank you in advance!
There are a couple of things in play here. First the tutorial you use is using plain Spring not Spring Boot. Which means a manually configured EntityManagerFactory on which you directly can set the provider specific properties. Like hibernate.cache.use_second_level_cache.
As you decided to use Spring Boot you don't have a manually configured EntityManagerFactory (although you could!). Which means you are using an autoconfigured EntityManagerFactory. Properties for this reside in the spring.jpa namespace for properties.
As it isn't feasible to specify properties for each and every extension for Hibernate (or other JPA providers) only some commonly used ones are exposed like spring.jpa.generate-ddl and a few provider specific ones in the spring.jpa.hibernate namespace. However to set all the other properties in an autoconfigured way there needed to be something else. Hence the spring.jpa.properties prefix. Anything specified in there will be passed on as is (without the said prefix ofcourse) to the EntityManagerFactory for configuration.

How to configure maxDegreeOfParallelism for cosmosdb in Springboot?

I want to configure the CosmosQueryRequestOptions.maxDegreeOfParallelism while using the CosmosRepository. I didn't find any documentation around it.
This blog shows how to configure and use this setting through a custom client, but I want to use the repository instead. https://medium.com/#middha.nishant173/improve-query-performance-with-azure-cosmosdb-java-sdk-v4-db1fc54cb484
CosmosQueryRequestOptions is implementation detail for Spring Data Cosmos SDK, so customers cannot set it through spring application.
This can be implemented as a new feature, and can be exposed through application.properties via query.maxDegreeOfParallelism - which customers can opt in if they want.
Default value for maxDegreeOfParallelism is 0, which is the right value for single partition queries. For cross partition queries in the current SDK version, you can get the cosmosClient through spring boot applicationContext and run the query directly against the client. This example shows how to do it - https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/cosmos/azure-spring-data-cosmos-test/src/test/java/com/azure/spring/data/cosmos/repository/integration/PageableAddressRepositoryIT.java#L144

Valid syntax for autowired properties in spring

I have been looking for an explanation of how Spring Framework will look for #AutoWired properties. I have noticed that when using the hikariCP library that setting either of the properties below will result in a correct max pool size.
spring.datasource.hikari.maximumPoolSize=3
or
spring.datasource.hikari.maximum-pool-size=3
Does Spring use both camel case and hyphen separated to lookup autowired properties? Where might I find an explanation in the spring docs?
That isn't a feature of the core Spring Framework but rather a feature of Spring Boot.
Spring Boot has a feature called relaxed binding which is used for properties mapped to a class annotated/used with #ConfigurationProperties. Each property that is being bound can be used with camel-case, dashes or even uppercase with dashes (generally used for environment variables!).
So all of these will work in the same way (the latter is often used to pass it as an environment or system variable).
spring.datasource.hikari.maximumPoolSize=3
spring.datasource.hikari.maximum-pool-size=3
SPRING_DATASOURCE_HIKARI_MAXIMUMPOOLSIZE=3
There are valid and invalid properties, but Spring's #ConfigurationProperties, which used mostly for loading configurations, works with both forms of properties.
The issue can be if any framework, library, etc. use property separately, without #ConfigurationProperties. In this case, you will have runtime exception (or null value).
Most default, base, popular properties are here: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html

Spring Boot best practices for hiding or encrypting passwords

I have been using the Spring Framework for about 4 years now, and now Spring Boot for the last couple of months. My Spring MVC applications are usually deployed on a Java EE container such as JBoss/WildFly or WebLogic. Doing so allows me to use JNDI for things like datasources or any other sensitive data that involve secrets/passwords. That makes my app "consume" that JNDI resource based on its name.
Now with Spring Boot and especially for self-contained microservices (embedded tomcat), that information is now stored within the application (application.properties and/or in Spring Java Config classes), so versioned in Git.
That makes that information a lot more exposed to other developers, which I'm not very comfortable with. I also don't like having those details show up in SonarQube and Jenkins (through workspaces).
Question is: Are there any best practices for this specific requirement?
* UPDATE *
I see some articles here and there about the use of Jasypt, but I wonder if it's still a valid library to use since the last stable release is dated from 2014.
Thank you
You could consider using a vault. Spring supports a few of them out of the box. You can find more information here http://projects.spring.io/spring-vault/.
If you have spring cloud in your stack, then it's very easy. Use encrypt the value and put it in the application properties. Follow the instruction mentioned here.
Other way is, set the values as environmental variables and using the environmental variables in the application properties. Instructions here

Spring Data GemFire Region entry expiration (Time-To-Live) error

I have a Spring Data GemFire Region that's configured using annotations below:
#TimeToLiveExpiration(timeout = "100", action = "INVALIDATE")
#PartitionRegion(name = "blockedIPCache")
class BlockedIpEntityType { ... }
My application is a Spring Boot application and I used the following annotations to configure SDG:
#PeerCacheApplication
#EnableGemfireCaching
#EnableCachingDefinedRegions(clientRegionShortcut = ClientRegionShortcut.LOCAL, serverRegionShortcut = RegionShortcut.LOCAL)
#EnableStatistics
#EnableExpiration
#EnableEntityDefinedRegions(basePackageClasses = {...})
#EnableGemfireRepositories(basePackages = {...})
class GemFireConfiguration { ... }
All I want is to insert an object using a Spring Data GemFire Repository and after awhile the entry will be invalidated.
But, I face this Exception when I start my application...
Caused by: java.lang.IllegalStateException: Cannot set idle timeout when statistics are disabled.
at org.apache.geode.internal.cache.AbstractRegion.setCustomEntryIdleTimeout(AbstractRegion.java:1157) ~[geode-core-9.1.1.jar:?]
at org.springframework.data.gemfire.config.annotation.ExpirationConfiguration$ExpirationPolicyMetaData.configure(ExpirationConfiguration.java:511) ~[spring-data-gemfire-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.springframework.data.gemfire.config.annotation.ExpirationConfiguration$1.postProcessAfterInitialization(ExpirationConfiguration.java:160) ~[spring-data-gemfire-2.0.6.RELEASE.jar:2.0.6.RELEASE]
...
This happens exactly when Spring tries to autowire my Repository related to the Region configured above.
So what I'm doing wrong? And, is there a way to enable Region statistics using Java configuration or Annotations?
Note: Using Spring Data GemFire 2.0.6, Spring 5.0.5, Spring Boot 2.0.1 used in the project.
It turns out, you did not do anything wrong. Unfortunately, you stumbled across a bug(!), for which I have already filed SGF-747 and fixed. I am sorry for the inconvenience this issue may have caused you.
We are planning a Spring Data Lovelace M3 (Milestone 3) release tomorrow (Thursday, 5/17, CET). The release schedule is visible from Spring Release Calendar. All dates are tentative.
As such, you could try the new Spring Data for Pivotal GemFire (SDG) Lovelace bits (i.e. 2.1.0.M3) with the fix. SDG 2.1.0. should work just fine with Spring Boot 2.0.1/2.RELEASE and Spring 5.0.5/6.RELEASE.
However, if you are expecting to get GA bits for SDG containing this fix, then you will have to wait for the next Spring Data Kay Service Release (Kay SR8), or the Spring Data for Pivotal GemFire 2.0.8 Service Release. I am backing porting this fix.
Unfortunately, there is not another Spring Data Kay Service Release (i.e. Kay SR8) planned until probably around July 2nd or 3rd, right after Spring Framework 5.0.7 is released on Monday, July 2nd and just before Spring Boot 2.0.3 is released on Wednesday, July 4th, which is usually when we plan Spring Data Service Releases. Also, know that Spring Boot 2.0.x is based on Spring Data Kay, but should work just fine with SD Lovelace too, as I mentioned previously.
In the meantime, I will try to think of workaround where the convenience of the Annotations (e.g. #EnableEntityDefinedRegions) can still be used. I will post the workaround in SGF-747.
I see that you specified the clientRegionShortcut attribute in the #EnableCachingDefinedRegions annotation but have declared your application to be a #PeerCacheApplication. While there is no harm in doing so, the clientRegionShortcut attribute is useless in this case. Likewise, the serverRegionShortcut attribute would have no meaning if you are application were a #ClientCacheApplication instead; something to keep in mind.
Lastly, I wanted to let you know that the SDG #EnableStatistics annotation does not have the effect you probably think it does.
Specifically, SDG's #EnableStatistics annotation is concerned with enabling Pivotal GemFire's statistics "sampling" as explained here, which is configured by doing this, as also explained in the SDG #EnableStatistics annotation Javadoc, as well as referenced in the SDG Reference Guide.
The "statistics enabling" that ultimately needs to happen is by setting the Region's staticsEnabled attribute property when configuring and creating the Region (e.g. "blockedIPCache").
That is exactly what the #EnableExpiration annotation will indirectly guarantee now, with the fix in SGF-747, without the need to #EnableStatistics.
Anyway, I hope this all makes sense and helps.
Regards,
John

Resources