Unable to load spring.data application.properties in Spring WebFlux - spring-data

I'm unable to load spring.data configuration from application.properties in Spring WebFlux
Here's what I added in application.properties
spring.data.web.pageable.default-page-size=2
spring.data.web.pageable.max-page-size=2147483647
The same properties work in Spring MVC
Inside SpringDataWebAutoConfiguration, there is #ConditionalOnClass({PageableHandlerMethodArgumentResolver.class, WebMvcConfigurer.class}) which may be the cause why it's not loaded in Spring WebFlux because it doens't have WebMvcConfigurer
Is it the problem?
How to load the properties in WebFlux?

In Spring Webflux there is currently no customization available of the ReactivePageableHandlerMethodArgumentResolver with properties but you can customize it via WebFluxConfigurer.
#Configuration
class WebFluxConfiguration implements WebFluxConfigurer {
#Override
public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
var pageableResolver = new ReactivePageableHandlerMethodArgumentResolver();
pageableResolver.setMaxPageSize(Integer.MAX_VALUE);
pageableResolver.setFallbackPageable(PageRequest.of(0, 2));
configurer.addCustomResolver(pageableResolver);
}
}
You could also create your own properties binding with Configuration Properties now and pass the values to the setters.

Related

How to add a custom Credential Store to WildFly

Using steps from https://docs.wildfly.org/23/WildFly_Elytron_Security.html#Custom_CredentialStore
Created a SPI and Provider implementation. For now, just simple implementation with logs to see if it works.
Now I don't know how to add this do WildFly.
I packaged it into a module and:
tried to add a <extension module=...> ref on standalone.xml, but than it complains that it is not an extension;
tried to add as subsystem=domain:ee/global-modules/module, there is no error, but nor SPI or Provider have a hit;
tried to add as subsystem=elytron/provider-loader, then Provider is called (twice ??), but SPI not.
So, using provider-loader, how to use my custom provider?
Here a snippet of Provider impl:
// used WildFlyElytronCredentialStoreProvider as reference
public class TestCredentialStoreProvider extends WildFlyElytronBaseProvider {
private static final TestCredentialStoreProvider INSTANCE = new TestCredentialStoreProvider ();
public TestCredentialStoreProvider () {
super("TestCredentialStoreProvider ", "1.0", "Test CredentialStore Provider");
putService(new Service(this, "CredentialStore", "TestCredentialStore", "package.TestCredentialStore", emptyList, emptyMap));
}
public static TestCredentialStoreProvider getInstance() {
return INSTANCE;
}
}
Obs. Why provider is loaded twice?
Create a jar and containing your credential store and provider classes, and add it as a WildFly module with a dependency on org.wildfly.security.elytron. For example:
module add --name=org.wildfly.customcredstore --resources=/path/to/customcredstoreprovider.jar --dependencies=org.wildfly.security.elytron
Create a provider loader for your provider. For example:
/subsystem=elytron/provider-loader=myProviderLoader:add(class-names=[org.wildfly.security.mycustomcredstore.CustomProvider],module=org.wildfly.customcredstore)
You can add it to the list of initial providers and reload the server
/subsystem=elytron:write-attribute(name=initial-providers,value=myProviderLoader)
reload
You can check loaded providers:
/subsystem=elytron/provider-loader=myProviderLoader:read-attribute(name=loaded-providers)
Then to add a custom credential store with the provider you can use:
/subsystem=elytron/credential-store=mystore:add(providers=myProviderLoader,type=TestCredentialStore,credential-reference={clear-text='pass'})
There is also some docs on how to add custom elytron component here: https://docs.wildfly.org/26/WildFly_Elytron_Security.html#Custom_Components

How to add custom spring cloud gateway filter in Java config?

I've created a custom filter in Spring Cloud Gateway by extending the class with "LoggingGlobalPreFilter"
I have the following routes.
return builder.routes().route(r -> r.path("/first/**").uri("http://localhost:8222"))
.route(r -> r.path("/seconf/**").uri("http://localhost:8333")).build();
Not sure how to add custom filter there. All the articles on the internet are talking about configuring filters in .yml file.
Thanks!
#Component
public class CustomFilter implements GlobalFilter, Ordered {
}

Spring Integration JPA - Retrieving Outbound Gateway with Entity Graph

Is it possible to use entity graph in Jpa Retrieving Outbound Gateway?
#Bean
public IntegrationFlow findContract() {
return f -> f
.handle(Jpa.retrievingGateway(this.entityManagerFactory)
.entityClass(Contract.class)
//.parameterExpression("contractNumber", "payload"))
// set entityGraph name
;
}
I would like to use approach similar to Spring Data Jpa
public interface ContractRepository extends JpaRepository<Contract, Long> {
#EntityGraph(value = "contract.documents", type = EntityGraphType.LOAD)
Contract findByContractNumber(String contractNumber);
}
This is just not implemented in the Spring Integration.
Feel free to raise an appropriate JIRA for such an improvement. Of course, Contribution is welcome.
Meanwhile as a workaround you can use a #ServiceActivator (.handle() in Java DSL) to call that ContractRepository.findByContractNumber() method.

spring cloud programmatic metadata generation

Is there anyway that I can generate some metadata to add to the service when it registers.
We are moving from Eureka to Consul and I need to add a UUID value to the registered metadata when a service starts. So that later I can get this metadata value when I retrieve the service instances by name.
Some background: We were using this excellent front end UI from https://github.com/VanRoy/spring-cloud-dashboard. It is set to use the Eureka model for services in which you have an Application with a name. Each application will have multiple instances each with an instance id.
So with the eureka model there is a 2 level service description whereas the spring cloud model is a flat one where n instances each of which have a service id.
The flat model won't work with the UI that I referenced above since there is no distinction between application name and instance id which is the spring model these are the same.
So if I generate my own instance id and handle it through metadata then I can preserve some of the behaviour without rewriting the ui.
See the documentation on metadata and tags in spring cloud consul. Consul doesn't support metadata on service discovery yet, but spring cloud has a metadata abstraction (just a map of strings). In consul tags created with key=value style are parsed into that metadata map.
For example in, application.yml:
spring:
cloud:
consul:
discovery:
tags: foo=bar, baz
The above configuration will result in a map with foo→bar and baz→baz.
Based on Spencer's answer I added an EnvironmentPostProcessor to my code.
It works and I am able to add the metadata tag I want programmatically but it is a complement to the "tags: foo=bar, baz" element so it overrides that one. I will probably figure a way around it in the next day or so but I thougth I would add what I did for other who look at this answer and say, so what did you do?
first add a class as follows:
#Slf4j
public class MetaDataEnvProcessor implements EnvironmentPostProcessor, Ordered {
// Before ConfigFileApplicationListener
private int order = ConfigFileApplicationListener.DEFAULT_ORDER - 1;
private UUID instanceId = UUID.randomUUID();
#Override
public int getOrder() {
return this.order;
}
#Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("spring.cloud.consul.discovery.tags", "instanceId="+instanceId.toString());
MapPropertySource propertySource = new MapPropertySource("springCloudConsulTags", map);
environment.getPropertySources().addLast(propertySource);
}
}
then add a spring.factories in resources/META-INF with eht following line to add this processor
org.springframework.boot.env.EnvironmentPostProcessor=com.example.consul.MetaDataEnvProcessor
This works fine except for the override of what is in your application.yml file for tags

Creating a Spring 4 MVC project with annotations and no xml files

I'm new to Spring MVC and Hibernate. I'm trying to start a project by following tutorials but I have been running into problems as my project structure is not consistent with the tutorials I am reading.
I have downloaded the latest STS and I do see the option of creating an Spring MVC project. However it is based on Spring 3 and still uses XML files. From what I have read it looks like there is a way to do it without XML files since Spring 3. I prefer annotations over XML files greatly.
How can I create a Spring MVC 4 application that is based on annotations and relies on xml files minimally?
EDIT:
I want to create a web project
Here is a squeletal example of full java configuration. You will need :
a class extending AbstractAnnotationConfigDispatcherServletInitializer to replace the old web.xml file
one or more #Configuration annotaded class(es) to initialize the root context (replaces the old applicationContext.xml)
one or more #Configuration annotaded class(es) to initialize the DispatcherServlet context (replaces the old dispatcher-servlet.xml)
This is the web.xml :
public class WebAppConf extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// declare root context configuration classes
return new Class<?>[]{ RootConf.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
// declare servlet context configuration classes
return new Class<?>[]{ ServletConf.class };
}
#Override
protected String[] getServletMappings() {
// mapping of DispatcherServlet
return new String[]{"/"};
}
#Override
protected void customizeRegistration(Dynamic registration) {
// additional configuration, here for MultipartConfig
super.customizeRegistration(registration);
MultipartConfigElement multipartConf = new MultipartConfigElement("", 200000L, -1L, 0);
registration.setMultipartConfig(multipartConf);
}
}
RootConf will declare business model, service and dao beans and is not shown here.
ServletConf declares the controllers and servlet configuration :
#Configuration
#EnableWebMvc
// declare where to find annotated controllers
#ComponentScan({"org.example.web"})
public class ServletConf extends WebMvcConfigurerAdapter {
#Bean
MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
#Bean
ViewResolver internalViewResolver() {
// the view resolver bean ...
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
As said above, it is squeletal, but it comes from a working minimal example so you should be able to start with that and extend it at will. In my example, the above three classes live in a org.example.config package that will never be scanned for autodetecting other configuration classes or annotated beans.
Hope it helps ...
I know this doesn't answer your question fully, but hopefully the links will be useful.
WebApplicationInitializer - A 100% code based approach to configuration
as well as AnnotationConfigWebApplicationContext
Also, if you have the time, reading the relevant sections of Spring's MVC chapter of their documentation is helpful.
I Wish that this link will be helpful for you Spring security with annotation Mkyong
The latest versions of STS integrate the Spring guides from https://spring.io/guides directly, try the "Import Spring Getting Started Content" wizard. There are good guides included for creating a Spring Boot based web service, for example, among many others.