Reinit/reload SimpleUrlMapping in Spring Boot 2 - spring

We are using a SimpleUrlHandlerMapping in our Spring Boot 2.1 application to load mapping information from database:
#Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
simpleUrlHandlerMapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
simpleUrlHandlerMapping.setInterceptors(requestMonitoringInterceptor);
Map<String, Object> urlMap = getUrlMapFromDb();
simpleUrlHandlerMapping.setUrlMap(urlMap);
return simpleUrlHandlerMapping;
}
It works fine, but if the mapping is changed then we need to restart the server to load the new mapping during startup. The application administrator doesn't have server access so he/she is not able to restart the application.
Is there any way to reload the mapping from the application itself without restarting the server?

Reload just the war through tomcat manager gui

Related

Spring Boot 2.3.0.M4, Cassandra, and SSL

I have been using ClusterBuilderCustomizer to customize the SSL connection between my Spring Boot application (2.2.5.RELEASE) and the Cassandra database. After migrating to Spring Boot 2.3.0.M4, my code no longer compiles as the ClusterBuilderCustomizer doesn't exist anymore.
As per Spring Boot 2.3.0 release notes, it has been replaced with DriverConfigLoaderBuilderCustomizer and CqlSessionBuilderCustomizer. Does anyone have a working example on how to use any of these customizer classes with SSL?
You just need to declare two beans having these types:
#Bean
public CqlSessionBuilderCustomizer cqlSessionBuilderCustomizer() {
return cqlSessionBuilder -> cqlSessionBuilder
.withNodeStateListener(new MyNodeStateListener())
.withSchemaChangeListener(new MySchemChangeListener());
}
#Bean
public DriverConfigLoaderBuilderCustomizer driverConfigLoaderBuilderCustomizer() {
return loaderBuilder -> loaderBuilder
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(10));
}
}
Use CqlSessionBuilderCustomizer to pass runtime objects to the session builder, e.g. node state listeners or schema change listeners.
Use DriverConfigLoaderBuilderCustomizer to programmatically customize the driver configuration. See the driver docs for more information on how to programmatically configure the driver.

How to configure DispatcherType's for SecurityFilterAutoConfiguration?

I have a Spring Boot (2.1.5) application which uses the SecurityFilterAutoConfiguration feature. During registration of DelegatingFilterProxyRegistrationBean only REQUEST, ASYNC, ERROR DispatcherTypes are set. But I need FORWARD and INCLUDE as well.
The property security.filter-dispatcher-types from Spring Boot 1.x no longer works.
I can work around the problem by "overwriting" the DelegatingFilterProxyRegistrationBean as follows:
#Bean
#ConditionalOnBean(name = DEFAULT_FILTER_NAME)
#Primary
public DelegatingFilterProxyRegistrationBean customSecurityFilterChainRegistration(SecurityProperties securityProperties) {
DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(DEFAULT_FILTER_NAME);
registration.setOrder(securityProperties.getFilter().getOrder());
registration.setDispatcherTypes(allOf(DispatcherType.class));
return registration;
}
But that doesn't seem like a very elegant solution to me.
Is there a way to configure this for Spring Boot 2.1.x explicit?
You have to use spring.security.filter.dispatcher-types, see Spring Boot 2.0 Configuration Changelog.

Elastic PreBuiltTransportClient with spring boot creating memory leakage

I am creating the bean of elastic client using the following code. It's creating the memory leakage. I am using the spring boot 2.0.1.RELEASE and elastic rest client 5.6.8.
#Bean
public Client client() throws UnknownHostException {
Settings esSettings = Settings.builder()
.put("cluster.name", esClusterName)
.build();
return new PreBuiltTransportClient(esSettings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(esHost), esPort));
}
This is well known problem.
https://github.com/elastic/elasticsearch/issues/26048
I think you have one way to solve it
You could switch to elastic java rest client. https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html
Please check discussion here
https://discuss.elastic.co/t/are-there-memory-leaks-in-elasticsearchs-transportclient-5-4-3-or-is-my-code-flawed/91989

Is it possible to load properties from a web service during spring boot application startup?

I am building a new spring boot application deployable to bluemix (cloud foundry) which needs to do the following:
use spring-cloud-cloudfoundry-connector to discover user-provided "properties service": read the service URL and credentials from VCAP_APPLICATION env variable.
This step is completed.
connect to properties service via HTTP call, receive JSON response, parse individual property values and expose them as application properties (in Environment object?)
What would be the correct solution for this in spring-boot app?
In older non-boot Spring app, the property service call would be initiated early in Spring lifecycle by a class that extended PropertySourcesPlaceholderConfigurer and the property collection from the service would be handled inside postProcessBeanFactory() method call of the same class.
public class CustomPopertiesFactory
extends PropertySourcesPlaceholderConfigurer
implements EnvironmentAware {
private Properties properties;
getServiceCredentials() {
// parse VCAP_APPLICATION json
final String localVcapServices = System.getProperty("VCAP_SERVICES");
// extract url, username, pwd to connect to the service
}
connectToService () {
// via HTTP request using RestTemplate
// parse JSON response and add properties to this.properties
... this.properties.put("prop1", valueFromJson);
}
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
getServiceCredentials();
connectToService();
// load values from properties service into app properties
setProperties(properties);
// continue with lifecycle and load properties from other sources
super.postProcessBeanFactory(beanFactory);
}
}
That was painful to maintain and switch between cloud and local spring profiles IMO and I am wondering if spring boot has a better way of handling external properties.
I ended up replacing "properties service" with spring-cloud-config-server
and using spring-cloud-config-client
in my spring boot application to consume properties from spring-cloud-config-server.

When running a springboot app - using spring 5 - how are apache nio properties configured?

We are running a springboot application using the new reactive features. For downstream calls we are using the new WebClient provided by spring. When we configure the max threads - the configuration is honored. We would like to experiment with additional poller threads or changing some of the timeouts. However the nio specific apache configuration is not honored.
Any help is greatly appreciated!
in application.properties
server.tomcat.max-threads=3 <- this is working
server.tomcat.accept-count=1000 <- this is working
server.tomcat.poller-thread-count=5 <- this is not working/ignored
server.tomcat.poller-thread-priority=5 <- this is not working/ignored
server.tomcat.selector-timeout=2000 <- this is not working/ignored
The Connector that is used by Tomcat , e.g the NIO connector can be configured
by providing your own Customizer :
#Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(connector ->
((AbstractProtocol) connector.getProtocolHandler()).setMaxConnections(200));
// configure some more properties
return factory;
}
}
You can also read:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-configure-tomcat

Resources