BAEL-2302 UPDATED Spring Data REST HTTP Method customization example (#5594)
* BAEL-2302 Spring Data REST HTTP Method customization example * BAEL-2302 Spring Data REST - granular HTTP Methods control * BAEL-2302 Spring Data REST - fixed parent pom file version error * BAEL-2302 Fixing thymeleaf dependencies * BAEL-2302 Spring Data REST - fixed netty bootstrap * BAEL-2302 Spring Data REST - fixed netty test * BAEL-2302 Spring Data REST - fixed spring security oauth2 * BAEL-2302 - Fix oauth2 server deps
This commit is contained in:
parent
2d872af165
commit
52852b3a49
|
@ -77,6 +77,7 @@
|
|||
<rest-assured.version>3.1.0</rest-assured.version>
|
||||
<!-- plugins -->
|
||||
<thin.version>1.0.11.RELEASE</thin.version>
|
||||
<spring-boot.version>2.0.5.RELEASE</spring-boot.version>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
<oauth-auto.version>2.1.0.RELEASE</oauth-auto.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
|
@ -8,8 +8,8 @@ import org.springframework.http.server.reactive.HttpHandler;
|
|||
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
|
||||
import org.springframework.web.reactive.config.EnableWebFlux;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import reactor.ipc.netty.NettyContext;
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
import reactor.netty.DisposableServer;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
@ComponentScan(basePackages = {"com.baeldung.reactive.security"})
|
||||
@EnableWebFlux
|
||||
|
@ -18,17 +18,16 @@ public class SpringSecurity5Application {
|
|||
public static void main(String[] args) {
|
||||
try (AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(SpringSecurity5Application.class)) {
|
||||
context.getBean(NettyContext.class).onClose().block();
|
||||
context.getBean(DisposableServer.class).onDispose().block();
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NettyContext nettyContext(ApplicationContext context) {
|
||||
public DisposableServer nettyContext(ApplicationContext context) {
|
||||
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context)
|
||||
.build();
|
||||
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
|
||||
HttpServer httpServer = HttpServer.create("localhost", 8080);
|
||||
return httpServer.newHandler(adapter).block();
|
||||
return HttpServer.create().host("localhost").port(8080).handle(adapter).bind().block();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.baeldung.reactive;
|
||||
|
||||
import com.baeldung.web.reactive.Task;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
|
@ -7,13 +8,10 @@ import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
|
|||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import com.baeldung.web.reactive.Task;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.ipc.netty.NettyContext;
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
import reactor.netty.DisposableServer;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
|
@ -21,12 +19,11 @@ import static org.springframework.web.reactive.function.server.RequestPredicates
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
|
||||
public class Spring5ReactiveServerClientIntegrationTest {
|
||||
|
||||
private static NettyContext nettyContext;
|
||||
private static DisposableServer nettyServer;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
HttpServer server = HttpServer.create("localhost", 8080);
|
||||
HttpServer server = HttpServer.create().host("localhost").port(8080);
|
||||
RouterFunction<?> route = RouterFunctions.route(POST("/task/process"), request -> ServerResponse.ok()
|
||||
.body(request.bodyToFlux(Task.class)
|
||||
.map(ll -> new Task("TaskName", 1)), Task.class))
|
||||
|
@ -34,13 +31,12 @@ public class Spring5ReactiveServerClientIntegrationTest {
|
|||
.body(Mono.just("server is alive"), String.class)));
|
||||
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
|
||||
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
|
||||
nettyContext = server.newHandler(adapter)
|
||||
.block();
|
||||
nettyServer = server.handle(adapter).bind().block();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void shutDown() {
|
||||
nettyContext.dispose();
|
||||
nettyServer.dispose();
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
|
|
@ -31,10 +31,15 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- oauth2 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth.boot</groupId>
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<version>${oauth-auto.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-client</artifactId>
|
||||
|
@ -58,12 +63,6 @@
|
|||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth.boot</groupId>
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -79,4 +78,4 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package com.baeldung.config;
|
||||
|
||||
import com.baeldung.models.WebsiteUser;
|
||||
import com.baeldung.projections.CustomBook;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
|
||||
|
||||
import com.baeldung.projections.CustomBook;
|
||||
|
||||
import org.springframework.data.rest.core.mapping.ExposureConfiguration;
|
||||
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
@Configuration
|
||||
public class RestConfig extends RepositoryRestConfigurerAdapter{
|
||||
public class RestConfig implements RepositoryRestConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration repositoryRestConfiguration){
|
||||
repositoryRestConfiguration.getProjectionConfiguration().addProjection(CustomBook.class);
|
||||
ExposureConfiguration config = repositoryRestConfiguration.getExposureConfiguration();
|
||||
config.forDomainType(WebsiteUser.class).withItemExposure((metadata, httpMethods) ->
|
||||
httpMethods.disable(HttpMethod.PATCH));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,32 @@
|
|||
package com.baeldung.repositories;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
||||
import org.springframework.data.rest.core.annotation.RestResource;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import com.baeldung.models.WebsiteUser;
|
||||
|
||||
@CrossOrigin
|
||||
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
|
||||
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {
|
||||
|
||||
|
||||
@Override
|
||||
@RestResource(exported = false)
|
||||
void delete(WebsiteUser entity);
|
||||
|
||||
@Override
|
||||
@RestResource(exported = false)
|
||||
void deleteAll();
|
||||
|
||||
@Override
|
||||
@RestResource(exported = false)
|
||||
void deleteAll(Iterable<? extends WebsiteUser> entities);
|
||||
|
||||
@Override
|
||||
@RestResource(exported = false)
|
||||
void deleteById(Long aLong);
|
||||
|
||||
@RestResource(path = "byEmail", rel = "customFindMethod")
|
||||
WebsiteUser findByEmail(@Param("email") String email);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package com.baeldung.validator;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
|
||||
|
||||
import com.baeldung.SpringDataRestApplication;
|
||||
import com.baeldung.models.WebsiteUser;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -17,9 +14,10 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import com.baeldung.SpringDataRestApplication;
|
||||
import com.baeldung.models.WebsiteUser;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)
|
||||
|
@ -84,4 +82,30 @@ public class SpringDataRestValidatorIntegrationTest {
|
|||
mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().isNotAcceptable()).andExpect(redirectedUrl(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeletingCorrectUser_thenCorrectStatusCodeAndResponse() throws Exception {
|
||||
WebsiteUser user = new WebsiteUser();
|
||||
user.setEmail("john.doe@john.com");
|
||||
user.setName("John Doe");
|
||||
mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().is2xxSuccessful()).andExpect(redirectedUrl("http://localhost/users/1"));
|
||||
mockMvc.perform(delete("/users/1").contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().isMethodNotAllowed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSearchingByEmail_thenCorrectStatusCodeAndResponse() throws Exception {
|
||||
WebsiteUser user = new WebsiteUser();
|
||||
user.setEmail("john.doe@john.com");
|
||||
user.setName("John Doe");
|
||||
mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().is2xxSuccessful()).andExpect(redirectedUrl("http://localhost/users/1"));
|
||||
mockMvc.perform(get("/users/search/byEmail").param("email", user.getEmail()).contentType(MediaType.APPLICATION_JSON)).andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSearchingByEmailWithOriginalMethodName_thenErrorStatusCodeAndResponse() throws Exception {
|
||||
WebsiteUser user = new WebsiteUser();
|
||||
user.setEmail("john.doe@john.com");
|
||||
user.setName("John Doe");
|
||||
mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().is2xxSuccessful()).andExpect(redirectedUrl("http://localhost/users/1"));
|
||||
mockMvc.perform(get("/users/search/findByEmail").param("email", user.getEmail()).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isNotFound());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
|
||||
<properties>
|
||||
<rest-assured.version>3.1.0</rest-assured.version>
|
||||
<oauth.version>2.3.3.RELEASE</oauth.version>
|
||||
<oauth-auto.version>2.0.1.RELEASE</oauth-auto.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -20,11 +20,10 @@
|
|||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<version>${oauth.version}</version>
|
||||
<groupId>org.springframework.security.oauth.boot</groupId>
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<version>${oauth-auto.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
|
|
@ -3,15 +3,11 @@ package org.baeldung.config;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.config.annotation.*;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class UiWebConfig extends WebMvcConfigurerAdapter {
|
||||
public class UiWebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
|
@ -25,7 +21,6 @@ public class UiWebConfig extends WebMvcConfigurerAdapter {
|
|||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
super.addViewControllers(registry);
|
||||
registry.addViewController("/")
|
||||
.setViewName("forward:/index");
|
||||
registry.addViewController("/index");
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
|
|
@ -3,15 +3,11 @@ package org.baeldung.config;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.config.annotation.*;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class UiWebConfig extends WebMvcConfigurerAdapter {
|
||||
public class UiWebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
|
@ -25,7 +21,6 @@ public class UiWebConfig extends WebMvcConfigurerAdapter {
|
|||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
super.addViewControllers(registry);
|
||||
registry.addViewController("/")
|
||||
.setViewName("forward:/index");
|
||||
registry.addViewController("/index");
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
Loading…
Reference in New Issue