Merge branch 'eugenp:master' into danielmcnally285_string_to_long
This commit is contained in:
commit
3dbd82fe17
@ -8,4 +8,5 @@ The code examples related to different libraries are each in their own module.
|
||||
Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-modules) we already have separate modules. Please make sure to have a look at the existing modules in such cases.
|
||||
|
||||
### Relevant articles
|
||||
- [Find Files by Extension in Specified Directory in Java](https://www.baeldung.com/java-recursive-search-directory-extension-match)
|
||||
- More articles [[<-- prev]](/libraries-6)
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
<relativePath>../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@ -20,9 +20,8 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<version>${spring-security-oauth2.version}</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
@ -68,6 +67,29 @@
|
||||
<artifactId>jsch</artifactId>
|
||||
<version>${jsch.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>2.3.0.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-authorization-server</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.sshd</groupId>
|
||||
<artifactId>sshd-core</artifactId>
|
||||
@ -125,7 +147,6 @@
|
||||
<bouncycastle.version>1.68</bouncycastle.version>
|
||||
<jsch.version>0.1.55</jsch.version>
|
||||
<apache-mina.version>2.5.1</apache-mina.version>
|
||||
<spring-security-oauth2.version>2.4.0.RELEASE</spring-security-oauth2.version>
|
||||
<xacml4j.version>1.4.0</xacml4j.version>
|
||||
</properties>
|
||||
|
||||
|
@ -4,7 +4,6 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
@ServletComponentScan
|
||||
public class ScribejavaApplication {
|
||||
@ -13,5 +12,4 @@ public class ScribejavaApplication {
|
||||
SpringApplication.run(ScribejavaApplication.class, args);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
@RestController
|
||||
public class GoogleController {
|
||||
|
@ -2,15 +2,14 @@ package com.baeldung.scribejava.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.security.DeclareRoles;
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.HttpConstraint;
|
||||
import javax.servlet.annotation.ServletSecurity;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.annotation.security.DeclareRoles;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.HttpConstraint;
|
||||
import jakarta.servlet.annotation.ServletSecurity;
|
||||
import jakarta.servlet.annotation.WebServlet;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet(name="rbac", urlPatterns = {"/protected"})
|
||||
@DeclareRoles("USER")
|
||||
|
@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.security.Principal;
|
||||
|
||||
@RestController(value = "/user")
|
||||
|
@ -1,45 +1,103 @@
|
||||
package com.baeldung.scribejava.oauth;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
||||
|
||||
@Configuration
|
||||
@EnableAuthorizationServer
|
||||
public class AuthServiceConfig extends AuthorizationServerConfigurerAdapter {
|
||||
@EnableWebSecurity
|
||||
public class AuthServiceConfig {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("authenticationManagerBean")
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
|
||||
oauthServer.tokenKeyAccess("permitAll()")
|
||||
.checkTokenAccess("isAuthenticated()");
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilter(HttpSecurity http) throws Exception {
|
||||
http.headers( it -> it.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
|
||||
.csrf(AbstractHttpConfigurer::disable);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
||||
clients.inMemory()
|
||||
.withClient("baeldung_api_key")
|
||||
.secret("baeldung_api_secret")
|
||||
.authorizedGrantTypes("password","refresh_token")
|
||||
.scopes("read","write").autoApprove(true);
|
||||
@Bean
|
||||
public InMemoryUserDetailsManager userDetailsService() {
|
||||
UserDetails user = User.withUsername("baeldung")
|
||||
.password("scribejava")
|
||||
.roles("USER")
|
||||
.build();
|
||||
|
||||
return new InMemoryUserDetailsManager(user);
|
||||
}
|
||||
@Bean
|
||||
public RegisteredClientRepository registeredClientRepository() {
|
||||
RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
|
||||
.clientId("baeldung_api_key")
|
||||
.clientSecret("baeldung_api_secret")
|
||||
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
|
||||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
|
||||
.scope("read")
|
||||
.scope("write")
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())
|
||||
.build();
|
||||
|
||||
return new InMemoryRegisteredClientRepository(oidcClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
||||
endpoints
|
||||
.authenticationManager(authenticationManager)
|
||||
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
|
||||
@Bean
|
||||
@Order(1)
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
|
||||
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
|
||||
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
|
||||
http
|
||||
// Redirect to the login page when not authenticated from the
|
||||
// authorization endpoint
|
||||
.exceptionHandling((exceptions) -> exceptions
|
||||
.defaultAuthenticationEntryPointFor(
|
||||
new LoginUrlAuthenticationEntryPoint("/login"),
|
||||
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
|
||||
)
|
||||
)
|
||||
// Accept access tokens for User Info and/or Client Registration
|
||||
.oauth2ResourceServer((resourceServer) -> resourceServer
|
||||
.jwt(Customizer.withDefaults()));
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(2)
|
||||
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
|
||||
throws Exception {
|
||||
http
|
||||
.authorizeHttpRequests((authorize) -> authorize
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
// Form login handles the redirect to the login page from the
|
||||
// authorization server filter chain
|
||||
.formLogin(Customizer.withDefaults());
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
package com.baeldung.scribejava.oauth;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableResourceServer
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.headers().frameOptions().disable()
|
||||
.and()
|
||||
.csrf().disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication()
|
||||
.withUser("baeldung")
|
||||
.password("scribejava")
|
||||
.roles("USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
|
||||
|
||||
@EnableResourceServer
|
||||
@Configuration
|
||||
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/user/me").authenticated()
|
||||
.and()
|
||||
.csrf().disable();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
@Component
|
||||
public class GoogleService {
|
||||
|
||||
|
@ -5,7 +5,7 @@ import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
public class MyService {
|
||||
|
@ -5,7 +5,7 @@ import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.oauth.OAuth10aService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
public class TwitterService {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.baeldung.hibernate;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -74,5 +75,13 @@ public class CustomClassIntegrationTest {
|
||||
assertEquals("Sales", result.getDepartmentName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCastResultQueryToList_ThenListOfResultIsReturned() {
|
||||
Query<Result> query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name) "
|
||||
+ "from DeptEmployee m");
|
||||
List<Result> results = query.list();
|
||||
assertNotNull(results);
|
||||
assertEquals(1, results.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ApplicationConfig {
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget.entity;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
@Column(name = "first_name")
|
||||
private String firstName;
|
||||
@Column(name = "second_name")
|
||||
private String secondName;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(final Long id, final String firstName, final String secondName) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.secondName = secondName;
|
||||
}
|
||||
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(final String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getSecondName() {
|
||||
return secondName;
|
||||
}
|
||||
|
||||
public void setSecondName(final String secondName) {
|
||||
this.secondName = secondName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final User user = (User) o;
|
||||
|
||||
if (!Objects.equals(id, user.id)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(firstName, user.firstName)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(secondName, user.secondName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = id != null ? id.hashCode() : 0;
|
||||
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||
result = 31 * result + (secondName != null ? secondName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" +
|
||||
"id=" + id +
|
||||
", firstName='" + firstName + '\'' +
|
||||
", secondName='" + secondName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget.repository;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Repository
|
||||
public interface NewTransactionUserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
User getReferenceById(Long id);
|
||||
|
||||
@Override
|
||||
Optional<User> findById(Long id);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget.repository;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface SimpleUserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget.service;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import com.baeldung.spring.data.persistence.findvsget.repository.SimpleUserRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class NonTransactionalUserReferenceService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NonTransactionalUserReferenceService.class);
|
||||
private SimpleUserRepository repository;
|
||||
|
||||
public User findUserReference(final long id) {
|
||||
log.info("Before requesting a user");
|
||||
final User user = repository.getReferenceById(id);
|
||||
log.info("After requesting a user");
|
||||
return user;
|
||||
}
|
||||
|
||||
public User findAndUseUserReference(final long id) {
|
||||
final User user = repository.getReferenceById(id);
|
||||
log.info("Before accessing a username");
|
||||
final String firstName = user.getFirstName();
|
||||
log.info("This message shouldn't be displayed because of the thrown exception: {}", firstName);
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setRepository(final SimpleUserRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget.service;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import com.baeldung.spring.data.persistence.findvsget.repository.SimpleUserRepository;
|
||||
import java.util.Optional;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SimpleUserService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SimpleUserService.class);
|
||||
private final SimpleUserRepository repository;
|
||||
|
||||
public SimpleUserService(final SimpleUserRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public User findUser(final long id) {
|
||||
log.info("Before requesting a user in a findUser method");
|
||||
final Optional<User> optionalUser = repository.findById(id);
|
||||
log.info("After requesting a user in a findUser method");
|
||||
final User user = optionalUser.orElse(null);
|
||||
log.info("After unwrapping an optional in a findUser method");
|
||||
return user;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget.service;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class TransactionalUserReferenceService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TransactionalUserReferenceService.class);
|
||||
private JpaRepository<User, Long> repository;
|
||||
|
||||
@Transactional
|
||||
public User findUserReference(final long id) {
|
||||
log.info("Before requesting a user");
|
||||
final User user = repository.getReferenceById(id);
|
||||
log.info("After requesting a user");
|
||||
return user;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public User findAndUseUserReference(final long id) {
|
||||
final User user = repository.getReferenceById(id);
|
||||
log.info("Before accessing a username");
|
||||
final String firstName = user.getFirstName();
|
||||
log.info("After accessing a username: {}", firstName);
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setRepository(final JpaRepository<User, Long> repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget;
|
||||
|
||||
import static com.baeldung.spring.data.persistence.findvsget.UserProvider.userSource;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import com.baeldung.spring.data.persistence.findvsget.repository.SimpleUserRepository;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest(classes = ApplicationConfig.class, properties = {
|
||||
"spring.jpa.generate-ddl=true",
|
||||
"spring.jpa.show-sql=false"
|
||||
})
|
||||
abstract class DatabaseConfigurationBaseIntegrationTest {
|
||||
|
||||
private static final int NUMBER_OF_USERS = 10;
|
||||
|
||||
@Autowired
|
||||
private SimpleUserRepository repository;
|
||||
|
||||
@BeforeEach
|
||||
void populateDatabase() {
|
||||
final List<User> users = userSource()
|
||||
.map(Arguments::get)
|
||||
.map(s -> new User(((Long) s[0]), s[1].toString(), s[2].toString()))
|
||||
.collect(Collectors.toList());
|
||||
repository.saveAll(users);
|
||||
assumeThat(repository.findAll()).hasSize(NUMBER_OF_USERS);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void clearDatabase() {
|
||||
repository.deleteAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import com.baeldung.spring.data.persistence.findvsget.service.SimpleUserService;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@DisplayName("findBy test:")
|
||||
class FindUserIntegrationIntegrationTest extends DatabaseConfigurationBaseIntegrationTest {
|
||||
|
||||
|
||||
@Autowired
|
||||
private SimpleUserService service;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(UserProvider.class)
|
||||
@DisplayName("when looking for a user by an existing ID returns a user")
|
||||
void whenGettingUserByCorrectIdThenReturnUser(Long id, String firstName, String lastName) {
|
||||
final User expected = new User(id, firstName, lastName);
|
||||
final User actual = service.findUser(id);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("when looking for a user by a non-existing ID returns null")
|
||||
@ValueSource(longs = {11, 12, 13})
|
||||
void whenGettingUserByIncorrectIdThenReturnNull(Long id) {
|
||||
assertThat(service.findUser(id)).isNull();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import com.baeldung.spring.data.persistence.findvsget.entity.User;
|
||||
import com.baeldung.spring.data.persistence.findvsget.repository.NewTransactionUserRepository;
|
||||
import com.baeldung.spring.data.persistence.findvsget.repository.SimpleUserRepository;
|
||||
import com.baeldung.spring.data.persistence.findvsget.service.NonTransactionalUserReferenceService;
|
||||
import com.baeldung.spring.data.persistence.findvsget.service.TransactionalUserReferenceService;
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
|
||||
@DisplayName("getReferenceBy test:")
|
||||
class GetReferenceIntegrationIntegrationTest extends DatabaseConfigurationBaseIntegrationTest {
|
||||
|
||||
private static final long EXISTING_ID = 1L;
|
||||
|
||||
@Nested
|
||||
@DisplayName("given non-transactional service, even if user exists")
|
||||
class GivenNonTransactionalService {
|
||||
|
||||
@Autowired
|
||||
private NonTransactionalUserReferenceService nonTransactionalService;
|
||||
|
||||
@BeforeEach
|
||||
void configureService(@Autowired SimpleUserRepository repository) {
|
||||
nonTransactionalService.setRepository(repository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceUsingOutsideServiceThenThrowsException() {
|
||||
final User user = nonTransactionalService.findUserReference(EXISTING_ID);
|
||||
assertThatExceptionOfType(LazyInitializationException.class)
|
||||
.isThrownBy(user::getFirstName);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceNotUsingOutsideServiceThenDontThrowException() {
|
||||
final User user = nonTransactionalService.findUserReference(EXISTING_ID);
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceUsingInsideServiceThenThrowsException() {
|
||||
assertThatExceptionOfType(LazyInitializationException.class)
|
||||
.isThrownBy(() -> nonTransactionalService.findAndUseUserReference(EXISTING_ID));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("given transactional service with simple repository, even if user exists")
|
||||
class GivenTransactionalService {
|
||||
|
||||
@Autowired
|
||||
private TransactionalUserReferenceService transactionalService;
|
||||
|
||||
@BeforeEach
|
||||
void configureService(@Autowired SimpleUserRepository repository) {
|
||||
transactionalService.setRepository(repository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceUsingOutsideServiceThenThrowsException() {
|
||||
final User user = transactionalService.findUserReference(EXISTING_ID);
|
||||
assertThatExceptionOfType(LazyInitializationException.class)
|
||||
.isThrownBy(user::getFirstName);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceNotUsingOutsideServiceThenDontThrowException() {
|
||||
final User user = transactionalService.findUserReference(EXISTING_ID);
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(UserProvider.class)
|
||||
void whenFindUserReferenceUsingInsideServiceThenReturnsUser(Long id, String firstName, String lastName) {
|
||||
final User expected = new User(id, firstName, lastName);
|
||||
final User actual = transactionalService.findAndUseUserReference(id);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("given transactional service with new transaction repository, even if user exists")
|
||||
class GivenTransactionalServiceWithNewTransactionRepository {
|
||||
|
||||
@Autowired
|
||||
private TransactionalUserReferenceService transactionalServiceWithNewTransactionRepository;
|
||||
|
||||
@BeforeEach
|
||||
void configureService(@Autowired NewTransactionUserRepository repository) {
|
||||
transactionalServiceWithNewTransactionRepository.setRepository(repository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceUsingOutsideServiceThenThrowsException() {
|
||||
final User user = transactionalServiceWithNewTransactionRepository
|
||||
.findUserReference(EXISTING_ID);
|
||||
assertThatExceptionOfType(LazyInitializationException.class)
|
||||
.isThrownBy(user::getFirstName);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceNotUsingOutsideServiceThenDontThrowException() {
|
||||
final User user = transactionalServiceWithNewTransactionRepository.findUserReference(EXISTING_ID);
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindUserReferenceUsingInsideServiceThenThrowsExceptionDueToSeparateTransactions() {
|
||||
assertThatExceptionOfType(LazyInitializationException.class)
|
||||
.isThrownBy(() -> transactionalServiceWithNewTransactionRepository
|
||||
.findAndUseUserReference(EXISTING_ID));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.spring.data.persistence.findvsget;
|
||||
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class UserProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(final ExtensionContext context) {
|
||||
return userSource();
|
||||
}
|
||||
|
||||
static Stream<Arguments> userSource() {
|
||||
return Stream.of(
|
||||
Arguments.of(1L, "Saundra", "Krystek"),
|
||||
Arguments.of(2L, "Korey", "Venners"),
|
||||
Arguments.of(3L, "Lory", "Daffey"),
|
||||
Arguments.of(4L, "Michail", "Spinella"),
|
||||
Arguments.of(5L, "Emanuel", "Geertje"),
|
||||
Arguments.of(6L, "Jervis", "Waugh"),
|
||||
Arguments.of(7L, "Chantal", "Soldan"),
|
||||
Arguments.of(8L, "Darnall", "Fanner"),
|
||||
Arguments.of(9L, "Cordelia", "Hindge"),
|
||||
Arguments.of(10L, "Lem", "Pitcock")
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.baeldung.caseinsensitiveenum.converter;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
public class CaseInsensitiveWeekDayConverter implements Converter<String, WeekDays> {
|
||||
|
||||
@Override
|
||||
public WeekDays convert(final String source) {
|
||||
try {
|
||||
return WeekDays.valueOf(source.trim());
|
||||
} catch (IllegalArgumentException exception) {
|
||||
return WeekDays.valueOf(source.trim().toUpperCase());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.baeldung.caseinsensitiveenum.converter;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
public class StrictNullableWeekDayConverter implements Converter<String, WeekDays> {
|
||||
@Override
|
||||
public WeekDays convert(final String source) {
|
||||
try {
|
||||
return WeekDays.valueOf(source.trim());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.baeldung.caseinsensitiveenum.nonconventionalweek;
|
||||
|
||||
public enum NonConventionalWeekDays {
|
||||
Mon$Day, Tues$DAY_, Wednes$day, THURS$day_, Fri$Day$_$, Satur$DAY_, Sun$Day
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.baeldung.caseinsensitiveenum.nonconventionalweek;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class NonConventionalWeekDaysHolder {
|
||||
|
||||
@Value("${monday}")
|
||||
private NonConventionalWeekDays monday;
|
||||
|
||||
@Value("${tuesday}")
|
||||
private NonConventionalWeekDays tuesday;
|
||||
|
||||
@Value("${wednesday}")
|
||||
private NonConventionalWeekDays wednesday;
|
||||
|
||||
@Value("${thursday}")
|
||||
private NonConventionalWeekDays thursday;
|
||||
|
||||
@Value("${friday}")
|
||||
private NonConventionalWeekDays friday;
|
||||
|
||||
@Value("${saturday}")
|
||||
private NonConventionalWeekDays saturday;
|
||||
|
||||
@Value("${sunday}")
|
||||
private NonConventionalWeekDays sunday;
|
||||
|
||||
public NonConventionalWeekDays getMonday() {
|
||||
return monday;
|
||||
}
|
||||
|
||||
public void setMonday(final NonConventionalWeekDays monday) {
|
||||
this.monday = monday;
|
||||
}
|
||||
|
||||
public NonConventionalWeekDays getTuesday() {
|
||||
return tuesday;
|
||||
}
|
||||
|
||||
public void setTuesday(final NonConventionalWeekDays tuesday) {
|
||||
this.tuesday = tuesday;
|
||||
}
|
||||
|
||||
public NonConventionalWeekDays getWednesday() {
|
||||
return wednesday;
|
||||
}
|
||||
|
||||
public void setWednesday(final NonConventionalWeekDays wednesday) {
|
||||
this.wednesday = wednesday;
|
||||
}
|
||||
|
||||
public NonConventionalWeekDays getThursday() {
|
||||
return thursday;
|
||||
}
|
||||
|
||||
public void setThursday(final NonConventionalWeekDays thursday) {
|
||||
this.thursday = thursday;
|
||||
}
|
||||
|
||||
public NonConventionalWeekDays getFriday() {
|
||||
return friday;
|
||||
}
|
||||
|
||||
public void setFriday(final NonConventionalWeekDays friday) {
|
||||
this.friday = friday;
|
||||
}
|
||||
|
||||
public NonConventionalWeekDays getSaturday() {
|
||||
return saturday;
|
||||
}
|
||||
|
||||
public void setSaturday(final NonConventionalWeekDays saturday) {
|
||||
this.saturday = saturday;
|
||||
}
|
||||
|
||||
public NonConventionalWeekDays getSunday() {
|
||||
return sunday;
|
||||
}
|
||||
|
||||
public void setSunday(final NonConventionalWeekDays sunday) {
|
||||
this.sunday = sunday;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.baeldung.caseinsensitiveenum.week;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SpELWeekDaysHolder {
|
||||
|
||||
@Value("#{'${monday}'.toUpperCase()}")
|
||||
private WeekDays monday;
|
||||
|
||||
@Value("#{'${tuesday}'.toUpperCase()}")
|
||||
private WeekDays tuesday;
|
||||
|
||||
@Value("#{'${wednesday}'.toUpperCase()}")
|
||||
private WeekDays wednesday;
|
||||
|
||||
@Value("#{'${thursday}'.toUpperCase()}")
|
||||
private WeekDays thursday;
|
||||
|
||||
@Value("#{'${friday}'.toUpperCase()}")
|
||||
private WeekDays friday;
|
||||
|
||||
@Value("#{'${saturday}'.toUpperCase()}")
|
||||
private WeekDays saturday;
|
||||
|
||||
@Value("#{'${sunday}'.toUpperCase()}")
|
||||
private WeekDays sunday;
|
||||
|
||||
public WeekDays getMonday() {
|
||||
return monday;
|
||||
}
|
||||
|
||||
public void setMonday(final WeekDays monday) {
|
||||
this.monday = monday;
|
||||
}
|
||||
|
||||
public WeekDays getTuesday() {
|
||||
return tuesday;
|
||||
}
|
||||
|
||||
public void setTuesday(final WeekDays tuesday) {
|
||||
this.tuesday = tuesday;
|
||||
}
|
||||
|
||||
public WeekDays getWednesday() {
|
||||
return wednesday;
|
||||
}
|
||||
|
||||
public void setWednesday(final WeekDays wednesday) {
|
||||
this.wednesday = wednesday;
|
||||
}
|
||||
|
||||
public WeekDays getThursday() {
|
||||
return thursday;
|
||||
}
|
||||
|
||||
public void setThursday(final WeekDays thursday) {
|
||||
this.thursday = thursday;
|
||||
}
|
||||
|
||||
public WeekDays getFriday() {
|
||||
return friday;
|
||||
}
|
||||
|
||||
public void setFriday(final WeekDays friday) {
|
||||
this.friday = friday;
|
||||
}
|
||||
|
||||
public WeekDays getSaturday() {
|
||||
return saturday;
|
||||
}
|
||||
|
||||
public void setSaturday(final WeekDays saturday) {
|
||||
this.saturday = saturday;
|
||||
}
|
||||
|
||||
public WeekDays getSunday() {
|
||||
return sunday;
|
||||
}
|
||||
|
||||
public void setSunday(final WeekDays sunday) {
|
||||
this.sunday = sunday;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.baeldung.caseinsensitiveenum.week;
|
||||
|
||||
public enum WeekDays {
|
||||
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.baeldung.caseinsensitiveenum.week;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class WeekDaysHolder {
|
||||
|
||||
@Value("${monday}")
|
||||
private WeekDays monday;
|
||||
|
||||
@Value("${tuesday}")
|
||||
private WeekDays tuesday;
|
||||
|
||||
@Value("${wednesday}")
|
||||
private WeekDays wednesday;
|
||||
|
||||
@Value("${thursday}")
|
||||
private WeekDays thursday;
|
||||
|
||||
@Value("${friday}")
|
||||
private WeekDays friday;
|
||||
|
||||
@Value("${saturday}")
|
||||
private WeekDays saturday;
|
||||
|
||||
@Value("${sunday}")
|
||||
private WeekDays sunday;
|
||||
|
||||
public WeekDays getMonday() {
|
||||
return monday;
|
||||
}
|
||||
|
||||
public void setMonday(final WeekDays monday) {
|
||||
this.monday = monday;
|
||||
}
|
||||
|
||||
public WeekDays getTuesday() {
|
||||
return tuesday;
|
||||
}
|
||||
|
||||
public void setTuesday(final WeekDays tuesday) {
|
||||
this.tuesday = tuesday;
|
||||
}
|
||||
|
||||
public WeekDays getWednesday() {
|
||||
return wednesday;
|
||||
}
|
||||
|
||||
public void setWednesday(final WeekDays wednesday) {
|
||||
this.wednesday = wednesday;
|
||||
}
|
||||
|
||||
public WeekDays getThursday() {
|
||||
return thursday;
|
||||
}
|
||||
|
||||
public void setThursday(final WeekDays thursday) {
|
||||
this.thursday = thursday;
|
||||
}
|
||||
|
||||
public WeekDays getFriday() {
|
||||
return friday;
|
||||
}
|
||||
|
||||
public void setFriday(final WeekDays friday) {
|
||||
this.friday = friday;
|
||||
}
|
||||
|
||||
public WeekDays getSaturday() {
|
||||
return saturday;
|
||||
}
|
||||
|
||||
public void setSaturday(final WeekDays saturday) {
|
||||
this.saturday = saturday;
|
||||
}
|
||||
|
||||
public WeekDays getSunday() {
|
||||
return sunday;
|
||||
}
|
||||
|
||||
public void setSunday(final WeekDays sunday) {
|
||||
this.sunday = sunday;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.caseinsensitiveenum;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.CaseInsensitiveStringToEnumConverterUnitTest.WeekDayConverterConfiguration;
|
||||
import com.baeldung.caseinsensitiveenum.converter.CaseInsensitiveWeekDayConverter;
|
||||
import com.baeldung.caseinsensitiveenum.providers.WeekDayHolderArgumentsProvider;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
@SpringBootTest(properties = {
|
||||
"monday=monday",
|
||||
"tuesday=tuesday",
|
||||
"wednesday=wednesday",
|
||||
"thursday=THURSDAY",
|
||||
"friday=Friday",
|
||||
"saturday=saturDAY",
|
||||
"sunday=sUndAy",
|
||||
}, classes = {WeekDaysHolder.class, WeekDayConverterConfiguration.class})
|
||||
class CaseInsensitiveStringToEnumConverterUnitTest {
|
||||
|
||||
public static class WeekDayConverterConfiguration {
|
||||
@Bean
|
||||
public ConversionService conversionService() {
|
||||
final DefaultConversionService defaultConversionService = new DefaultConversionService();
|
||||
defaultConversionService.addConverter(new CaseInsensitiveWeekDayConverter());
|
||||
return defaultConversionService;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private WeekDaysHolder holder;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(WeekDayHolderArgumentsProvider.class)
|
||||
void givenPropertiesWhenInjectEnumThenValueIsNull(
|
||||
Function<WeekDaysHolder, WeekDays> methodReference, WeekDays expected) {
|
||||
WeekDays actual = methodReference.apply(holder);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.caseinsensitiveenum;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.providers.WeekDayHolderArgumentsProvider;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest(properties = {
|
||||
"monday=Mon-Day!",
|
||||
"tuesday=TuesDAY#",
|
||||
"wednesday=Wednes@day",
|
||||
"thursday=THURSday^",
|
||||
"friday=Fri:Day_%",
|
||||
"saturday=Satur_DAY*",
|
||||
"sunday=Sun+Day",
|
||||
}, classes = WeekDaysHolder.class)
|
||||
class LenientStringToEnumConverterUnitTest {
|
||||
|
||||
@Autowired
|
||||
private WeekDaysHolder holder;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(WeekDayHolderArgumentsProvider.class)
|
||||
void givenPropertiesWhenInjectEnumThenValueIsPresent(
|
||||
Function<WeekDaysHolder, WeekDays> methodReference, WeekDays expected) {
|
||||
WeekDays actual = methodReference.apply(holder);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.caseinsensitiveenum;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDaysHolder;
|
||||
import com.baeldung.caseinsensitiveenum.providers.NonConventionalWeekDayHolderArgumentsProvider;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest(properties = {
|
||||
"monday=Mon-Day!",
|
||||
"tuesday=TuesDAY#",
|
||||
"wednesday=Wednes@day",
|
||||
"thursday=THURSday^",
|
||||
"friday=Fri:Day_%",
|
||||
"saturday=Satur_DAY*",
|
||||
"sunday=Sun+Day",
|
||||
}, classes = NonConventionalWeekDaysHolder.class)
|
||||
class NonConventionalStringToEnumLenientConverterUnitTest {
|
||||
|
||||
@Autowired
|
||||
private NonConventionalWeekDaysHolder holder;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(NonConventionalWeekDayHolderArgumentsProvider.class)
|
||||
void givenPropertiesWhenInjectEnumThenValueIsPresent(
|
||||
Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays> methodReference, NonConventionalWeekDays expected) {
|
||||
NonConventionalWeekDays actual = methodReference.apply(holder);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.caseinsensitiveenum;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.CaseInsensitiveStringToEnumConverterUnitTest.WeekDayConverterConfiguration;
|
||||
import com.baeldung.caseinsensitiveenum.converter.StrictNullableWeekDayConverter;
|
||||
import com.baeldung.caseinsensitiveenum.providers.SpELWeekDayHolderArgumentsProvider;
|
||||
import com.baeldung.caseinsensitiveenum.week.SpELWeekDaysHolder;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
@SpringBootTest(properties = {
|
||||
"monday=monday",
|
||||
"tuesday=tuesday",
|
||||
"wednesday=wednesday",
|
||||
"thursday=THURSDAY",
|
||||
"friday=Friday",
|
||||
"saturday=saturDAY",
|
||||
"sunday=sUndAy",
|
||||
}, classes = {SpELWeekDaysHolder.class, WeekDayConverterConfiguration.class})
|
||||
class SpELCaseInsensitiveStringToEnumConverterUnitTest {
|
||||
|
||||
public static class WeekDayConverterConfiguration {
|
||||
@Bean
|
||||
public ConversionService conversionService() {
|
||||
final DefaultConversionService defaultConversionService = new DefaultConversionService();
|
||||
defaultConversionService.addConverter(new StrictNullableWeekDayConverter());
|
||||
return defaultConversionService;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private SpELWeekDaysHolder holder;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(SpELWeekDayHolderArgumentsProvider.class)
|
||||
void givenPropertiesWhenInjectEnumThenValueIsNull(
|
||||
Function<SpELWeekDaysHolder, WeekDays> methodReference, WeekDays expected) {
|
||||
WeekDays actual = methodReference.apply(holder);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.caseinsensitiveenum;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.StrictStringToEnumConverterNegativeUnitTest.WeekDayConverterConfiguration;
|
||||
import com.baeldung.caseinsensitiveenum.converter.StrictNullableWeekDayConverter;
|
||||
import com.baeldung.caseinsensitiveenum.providers.WeekDayHolderArgumentsProvider;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
@SpringBootTest(properties = {
|
||||
"monday=monday",
|
||||
"tuesday=tuesday",
|
||||
"wednesday=wednesday",
|
||||
"thursday=thursday",
|
||||
"friday=friday",
|
||||
"saturday=saturday",
|
||||
"sunday=sunday",
|
||||
}, classes = {WeekDaysHolder.class, WeekDayConverterConfiguration.class})
|
||||
class StrictStringToEnumConverterNegativeUnitTest {
|
||||
|
||||
public static class WeekDayConverterConfiguration {
|
||||
@Bean
|
||||
public ConversionService conversionService() {
|
||||
final DefaultConversionService defaultConversionService = new DefaultConversionService();
|
||||
defaultConversionService.addConverter(new StrictNullableWeekDayConverter());
|
||||
return defaultConversionService;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private WeekDaysHolder holder;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(WeekDayHolderArgumentsProvider.class)
|
||||
void givenPropertiesWhenInjectEnumThenValueIsNull(
|
||||
Function<WeekDaysHolder, WeekDays> methodReference, WeekDays ignored) {
|
||||
WeekDays actual = methodReference.apply(holder);
|
||||
assertThat(actual).isNull();
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.caseinsensitiveenum;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.StrictStringToEnumConverterNegativeUnitTest.WeekDayConverterConfiguration;
|
||||
import com.baeldung.caseinsensitiveenum.converter.StrictNullableWeekDayConverter;
|
||||
import com.baeldung.caseinsensitiveenum.providers.WeekDayHolderArgumentsProvider;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
@SpringBootTest(properties = {
|
||||
"monday=MONDAY",
|
||||
"tuesday=TUESDAY",
|
||||
"wednesday=WEDNESDAY",
|
||||
"thursday=THURSDAY",
|
||||
"friday=FRIDAY",
|
||||
"saturday=SATURDAY",
|
||||
"sunday=SUNDAY",
|
||||
}, classes = {WeekDaysHolder.class, WeekDayConverterConfiguration.class})
|
||||
class StrictStringToEnumConverterPositiveUnitTest {
|
||||
|
||||
public static class WeekDayConverterConfiguration {
|
||||
@Bean
|
||||
public ConversionService conversionService() {
|
||||
final DefaultConversionService defaultConversionService = new DefaultConversionService();
|
||||
defaultConversionService.addConverter(new StrictNullableWeekDayConverter());
|
||||
return defaultConversionService;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private WeekDaysHolder holder;
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(WeekDayHolderArgumentsProvider.class)
|
||||
void givenPropertiesWhenInjectEnumThenValueIsNull(
|
||||
Function<WeekDaysHolder, WeekDays> methodReference, WeekDays expected) {
|
||||
WeekDays actual = methodReference.apply(holder);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.caseinsensitiveenum.providers;
|
||||
|
||||
|
||||
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.Fri$Day$_$;
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.Mon$Day;
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.Satur$DAY_;
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.Sun$Day;
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.THURS$day_;
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.Tues$DAY_;
|
||||
import static com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays.Wednes$day;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.nonconventionalweek.NonConventionalWeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class NonConventionalWeekDayHolderArgumentsProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
|
||||
return Stream.of(
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getMonday),Mon$Day),
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getTuesday),Tues$DAY_),
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getWednesday),Wednes$day),
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getThursday),THURS$day_),
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getFriday),Fri$Day$_$),
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getSaturday),Satur$DAY_),
|
||||
Arguments.of(((Function<NonConventionalWeekDaysHolder, NonConventionalWeekDays>) NonConventionalWeekDaysHolder::getSunday),Sun$Day)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.baeldung.caseinsensitiveenum.providers;
|
||||
|
||||
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.FRIDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.MONDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.SATURDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.SUNDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.THURSDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.TUESDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.WEDNESDAY;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.week.SpELWeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class SpELWeekDayHolderArgumentsProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
|
||||
return Stream.of(
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getMonday), MONDAY),
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getTuesday), TUESDAY),
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getWednesday), WEDNESDAY),
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getThursday), THURSDAY),
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getFriday), FRIDAY),
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getSaturday), SATURDAY),
|
||||
Arguments.of(((Function<SpELWeekDaysHolder, WeekDays>) SpELWeekDaysHolder::getSunday), SUNDAY)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.baeldung.caseinsensitiveenum.providers;
|
||||
|
||||
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.FRIDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.MONDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.SATURDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.SUNDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.THURSDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.TUESDAY;
|
||||
import static com.baeldung.caseinsensitiveenum.week.WeekDays.WEDNESDAY;
|
||||
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDays;
|
||||
import com.baeldung.caseinsensitiveenum.week.WeekDaysHolder;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class WeekDayHolderArgumentsProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
|
||||
return Stream.of(
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getMonday), MONDAY),
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getTuesday), TUESDAY),
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getWednesday), WEDNESDAY),
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getThursday), THURSDAY),
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getFriday), FRIDAY),
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getSaturday), SATURDAY),
|
||||
Arguments.of(((Function<WeekDaysHolder, WeekDays>) WeekDaysHolder::getSunday), SUNDAY)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
## Spring Reactive Performance
|
||||
|
||||
This module contains articles about reactive Spring Boot.
|
||||
|
||||
## Relevant Articles
|
||||
- [Reactor WebFlux vs Virtual Threads](https://www.baeldung.com/java-reactor-webflux-vs-virtual-threads)
|
||||
|
@ -11,8 +11,9 @@
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-security-modules</artifactId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@ -34,7 +35,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -81,11 +82,6 @@
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp.jstl</groupId>
|
||||
<artifactId>jstl-api</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
@ -100,6 +96,11 @@
|
||||
<version>${ehcache-core.version}</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -15,14 +15,14 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@SpringBootApplication
|
||||
@PropertySource({"classpath:persistence-h2.properties", "classpath:application-defaults.properties"})
|
||||
@EnableJpaRepositories(basePackages = {"com.baeldung.relationships.repositories"})
|
||||
@EnableWebMvc
|
||||
@Import(SpringSecurityConfig.class)
|
||||
public class AppConfig extends WebMvcConfigurerAdapter {
|
||||
public class AppConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
@ -41,7 +41,7 @@ public class AppConfig extends WebMvcConfigurerAdapter {
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||
em.setDataSource(dataSource());
|
||||
em.setPackagesToScan(new String[] { "com.baeldung.relationships.models" });
|
||||
em.setPackagesToScan("com.baeldung.relationships.models");
|
||||
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
|
||||
em.setJpaProperties(additionalProperties());
|
||||
return em;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.baeldung.relationships;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -13,6 +13,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
|
||||
@ -47,12 +48,10 @@ public class SpringSecurityConfig {
|
||||
|
||||
@Bean
|
||||
public UserDetailsManager users(HttpSecurity http) throws Exception {
|
||||
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class)
|
||||
.userDetailsService(userDetailsService)
|
||||
.passwordEncoder(encoder())
|
||||
.and()
|
||||
.authenticationProvider(authenticationProvider())
|
||||
.build();
|
||||
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
|
||||
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(encoder());
|
||||
authenticationManagerBuilder.authenticationProvider(authenticationProvider());
|
||||
AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
|
||||
|
||||
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
|
||||
jdbcUserDetailsManager.setAuthenticationManager(authenticationManager);
|
||||
@ -61,22 +60,16 @@ public class SpringSecurityConfig {
|
||||
|
||||
@Bean
|
||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||
return (web) -> web.ignoring()
|
||||
.antMatchers("/resources/**");
|
||||
return web -> web.ignoring().requestMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/login")
|
||||
.permitAll()
|
||||
.and()
|
||||
.formLogin()
|
||||
.permitAll()
|
||||
.successHandler(successHandler)
|
||||
.and()
|
||||
.csrf()
|
||||
.disable();
|
||||
http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
|
||||
authorizationManagerRequestMatcherRegistry.requestMatchers("/login").permitAll())
|
||||
.formLogin(httpSecurityFormLoginConfigurer ->
|
||||
httpSecurityFormLoginConfigurer.permitAll().successHandler(successHandler))
|
||||
.csrf(AbstractHttpConfigurer::disable);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ package com.baeldung.relationships.models;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
|
@ -3,14 +3,14 @@ package com.baeldung.relationships.models;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import jakarta.persistence.CollectionTable;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "Tweet")
|
||||
|
@ -3,11 +3,12 @@ package com.baeldung.relationships.repositories;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
|
||||
import com.baeldung.relationships.models.Tweet;
|
||||
|
||||
public interface TweetRepository extends PagingAndSortingRepository<Tweet, Long> {
|
||||
public interface TweetRepository extends PagingAndSortingRepository<Tweet, Long>, CrudRepository<Tweet, Long> {
|
||||
|
||||
@Query("SELECT twt FROM Tweet twt JOIN twt.likes AS lk WHERE lk = ?#{ principal?.username } OR twt.owner = ?#{ principal?.username }")
|
||||
Page<Tweet> getMyTweetsAndTheOnesILiked(Pageable pageable);
|
||||
|
@ -2,8 +2,8 @@ package com.baeldung.relationships.security;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.baeldung.relationships.security;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
@ -2,8 +2,11 @@ package com.baeldung.roles.custom.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
@ -14,14 +17,9 @@ public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.csrf()
|
||||
.disable()
|
||||
.authorizeRequests()
|
||||
.anyRequest()
|
||||
.authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.permitAll();
|
||||
http.csrf(AbstractHttpConfigurer::disable)
|
||||
.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.anyRequest().authenticated())
|
||||
.formLogin(AbstractAuthenticationFilterConfigurer::permitAll);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package com.baeldung.roles.custom.persistence;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.baeldung.roles.custom.persistence.dao.OrganizationRepository;
|
||||
import com.baeldung.roles.custom.persistence.dao.PrivilegeRepository;
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.baeldung.roles.custom.persistence.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Foo {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.baeldung.roles.custom.persistence.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Organization {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.baeldung.roles.custom.persistence.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Privilege {
|
||||
|
@ -2,17 +2,17 @@ package com.baeldung.roles.custom.persistence.model;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_table")
|
||||
@ -28,7 +28,9 @@ public class User {
|
||||
private String password;
|
||||
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
@JoinTable(name = "users_privileges", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
|
||||
@JoinTable(name = "users_privileges", joinColumns =
|
||||
@JoinColumn(name = "user_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
|
||||
private Set<Privilege> privileges;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
|
@ -6,10 +6,13 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@ -32,19 +35,12 @@ public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/login")
|
||||
.permitAll()
|
||||
.antMatchers("/foos/**")
|
||||
.access("isAuthenticated() and hasIpAddress('11.11.11.11')")
|
||||
.anyRequest()
|
||||
.authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.permitAll()
|
||||
.and()
|
||||
.csrf()
|
||||
.disable();
|
||||
http.authorizeHttpRequests(
|
||||
authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers("/login").permitAll()
|
||||
.requestMatchers("/foos/**")
|
||||
.access(new WebExpressionAuthorizationManager("isAuthenticated() and hasIpAddress('11.11.11.11')")).anyRequest().authenticated())
|
||||
.formLogin(AbstractAuthenticationFilterConfigurer::permitAll)
|
||||
.csrf(AbstractHttpConfigurer::disable);
|
||||
return http.build();
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@ package com.baeldung.roles.ip.web;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.baeldung.roles.custom.persistence.model.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -2,9 +2,9 @@ package com.baeldung.roles.rolesauthorities;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||
|
@ -10,6 +10,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
@ -42,33 +43,22 @@ public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||
return (web) -> web.ignoring()
|
||||
.antMatchers("/resources/**");
|
||||
return (web) -> web.ignoring().requestMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.csrf()
|
||||
.disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*")
|
||||
.permitAll()
|
||||
.antMatchers("/protectedbyrole")
|
||||
.hasRole("USER")
|
||||
.antMatchers("/protectedbyauthority")
|
||||
.hasAuthority("READ_PRIVILEGE")
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.failureUrl("/login?error=true")
|
||||
.permitAll()
|
||||
.and()
|
||||
.logout()
|
||||
.logoutSuccessHandler(myLogoutSuccessHandler)
|
||||
.invalidateHttpSession(false)
|
||||
.logoutSuccessUrl("/logout.html?logSucc=true")
|
||||
.deleteCookies("JSESSIONID")
|
||||
.permitAll();
|
||||
http.csrf(AbstractHttpConfigurer::disable)
|
||||
.authorizeHttpRequests(
|
||||
authorizationManagerRequestMatcherRegistry ->
|
||||
authorizationManagerRequestMatcherRegistry.requestMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*").permitAll()
|
||||
.requestMatchers("/protectedbyrole").hasRole("USER")
|
||||
.requestMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE"))
|
||||
.formLogin(httpSecurityFormLoginConfigurer ->
|
||||
httpSecurityFormLoginConfigurer.loginPage("/login").failureUrl("/login?error=true").permitAll())
|
||||
.logout(httpSecurityLogoutConfigurer ->
|
||||
httpSecurityLogoutConfigurer.logoutSuccessHandler(myLogoutSuccessHandler).invalidateHttpSession(false)
|
||||
.logoutSuccessUrl("/logout.html?logSucc=true").deleteCookies("JSESSIONID").permitAll());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,11 @@ package com.baeldung.roles.rolesauthorities.model;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
|
||||
@Entity
|
||||
public class Privilege {
|
||||
|
@ -2,13 +2,13 @@ package com.baeldung.roles.rolesauthorities.model;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
|
||||
@Entity
|
||||
public class Role {
|
||||
|
@ -2,17 +2,16 @@ package com.baeldung.roles.rolesauthorities.model;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_account")
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.baeldung.roles.rolesauthorities.persistence;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
import com.baeldung.roles.rolesauthorities.model.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -1,33 +1,28 @@
|
||||
package com.baeldung.roles.voter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
||||
|
||||
public class MinuteBasedVoter implements AccessDecisionVoter {
|
||||
public class MinuteBasedVoter implements AuthorizationManager<RequestAuthorizationContext> {
|
||||
|
||||
@Override
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
return true;
|
||||
public void verify(Supplier<Authentication> authentication, RequestAuthorizationContext object) {
|
||||
AuthorizationManager.super.verify(authentication, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int vote(Authentication authentication, Object object, Collection collection) {
|
||||
return authentication.getAuthorities()
|
||||
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext object) {
|
||||
return authentication.get().getAuthorities()
|
||||
.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.filter(r -> "ROLE_USER".equals(r) && LocalDateTime.now().getMinute() % 2 != 0)
|
||||
.findAny()
|
||||
.map(s -> ACCESS_DENIED)
|
||||
.orElse(ACCESS_ABSTAIN);
|
||||
.findAny().map(s -> new AuthorizationDecision(false))
|
||||
.orElse(new AuthorizationDecision(true));
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,19 @@
|
||||
package com.baeldung.roles.voter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.access.AccessDecisionManager;
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
import org.springframework.security.access.vote.AuthenticatedVoter;
|
||||
import org.springframework.security.access.vote.RoleVoter;
|
||||
import org.springframework.security.access.vote.UnanimousBased;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationManagers;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.access.expression.WebExpressionVoter;
|
||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@ -38,32 +34,20 @@ public class WebSecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.csrf()
|
||||
.disable()
|
||||
.authorizeRequests()
|
||||
.anyRequest()
|
||||
.authenticated()
|
||||
.accessDecisionManager(accessDecisionManager())
|
||||
.and()
|
||||
.formLogin()
|
||||
.permitAll()
|
||||
.and()
|
||||
.logout()
|
||||
.permitAll()
|
||||
.deleteCookies("JSESSIONID")
|
||||
.logoutSuccessUrl("/login");
|
||||
http.csrf(AbstractHttpConfigurer::disable)
|
||||
.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
|
||||
authorizationManagerRequestMatcherRegistry.anyRequest().authenticated()
|
||||
.anyRequest().access(accessDecisionManager()))
|
||||
.formLogin(AbstractAuthenticationFilterConfigurer::permitAll)
|
||||
.logout(httpSecurityLogoutConfigurer ->
|
||||
httpSecurityLogoutConfigurer.permitAll().deleteCookies("JSESSIONID")
|
||||
.logoutSuccessUrl("/login"));
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AccessDecisionManager accessDecisionManager() {
|
||||
List<AccessDecisionVoter<?>> decisionVoters = Arrays.asList(
|
||||
new WebExpressionVoter(),
|
||||
new RoleVoter(),
|
||||
new AuthenticatedVoter(),
|
||||
new MinuteBasedVoter());
|
||||
|
||||
return new UnanimousBased(decisionVoters);
|
||||
public AuthorizationManager<RequestAuthorizationContext> accessDecisionManager() {
|
||||
return AuthorizationManagers.allOf(new MinuteBasedVoter());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -11,9 +11,9 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.expression.spel.SpelEvaluationException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -25,7 +25,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -83,7 +83,7 @@ public class SpringDataWithSecurityIntegrationTest {
|
||||
userRepository.updateLastLogin(new Date());
|
||||
}
|
||||
|
||||
@Test(expected = InvalidDataAccessApiUsageException.class)
|
||||
@Test(expected = SpelEvaluationException.class)
|
||||
public void givenNoAppUserInSecurityContext_whenUpdateLastLoginAttempted_shouldFail() {
|
||||
userRepository.updateLastLogin(new Date());
|
||||
}
|
||||
@ -104,7 +104,7 @@ public class SpringDataWithSecurityIntegrationTest {
|
||||
} while (page.hasNext());
|
||||
}
|
||||
|
||||
@Test(expected = InvalidDataAccessApiUsageException.class)
|
||||
@Test(expected = SpelEvaluationException.class)
|
||||
public void givenNoAppUser_whenPaginatedResultsRetrievalAttempted_shouldFail() {
|
||||
Page<Tweet> page = null;
|
||||
do {
|
||||
|
@ -6,13 +6,13 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.apache.http.HttpHeaders;
|
||||
import com.baeldung.roles.custom.Application;
|
||||
import com.baeldung.roles.custom.persistence.model.Foo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.test.context.support.WithAnonymousUser;
|
||||
import org.springframework.security.test.context.support.WithUserDetails;
|
||||
|
@ -15,6 +15,12 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<spock-core.version>2.4-M1-groovy-4.0</spock-core.version>
|
||||
<groovy-all.version>4.0.16</groovy-all.version>
|
||||
<gmavenplus-plugin.version>3.0.2</gmavenplus-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
@ -23,9 +29,10 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<groupId>org.apache.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>${groovy-all.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -39,18 +46,34 @@
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
<goal>compileTests</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<testSources>
|
||||
<testSource>
|
||||
<directory>${project.basedir}/src/test/groovy</directory>
|
||||
<includes>
|
||||
<include>**/*.groovy</include>
|
||||
</includes>
|
||||
</testSource>
|
||||
</testSources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<configuration>
|
||||
<testSourceDirectory>src/test/groovy</testSourceDirectory>
|
||||
<includes>
|
||||
<include>**/*Specification.groovy</include>
|
||||
<include>**/*Test.groovy</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<spock-core.version>1.3-groovy-2.4</spock-core.version>
|
||||
<groovy-all.version>2.4.7</groovy-all.version>
|
||||
<gmavenplus-plugin.version>1.5</gmavenplus-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
11
testing-modules/groovy-spock/src/main/java/mocks/Book.java
Normal file
11
testing-modules/groovy-spock/src/main/java/mocks/Book.java
Normal file
@ -0,0 +1,11 @@
|
||||
package mocks;
|
||||
|
||||
public class Book {
|
||||
private String title;
|
||||
private String author;
|
||||
|
||||
Book(String title, String author) {
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package mocks;
|
||||
|
||||
public interface BookRepository {
|
||||
Book findById(Long id);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package mocks;
|
||||
|
||||
public class BookService {
|
||||
private final BookRepository repository;
|
||||
|
||||
public BookService(BookRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public Book getBookDetails(Long id) {
|
||||
return repository.findById(id);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package mocks;
|
||||
|
||||
public class MessageService {
|
||||
public String fetchMessage() {
|
||||
return UtilityClass.getMessage();
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package mocks;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ShoppingCart {
|
||||
private final Map<String, Integer> items = new HashMap<>();
|
||||
private double totalPrice = 0.0;
|
||||
|
||||
public void addItem(String item, int quantity) {
|
||||
items.put(item, items.getOrDefault(item, 0) + quantity);
|
||||
totalPrice += quantity * 2.00; // Example pricing
|
||||
}
|
||||
|
||||
public int getTotalItems() {
|
||||
return items.values().stream().mapToInt(Integer::intValue).sum();
|
||||
}
|
||||
|
||||
public double getTotalPrice() {
|
||||
return totalPrice;
|
||||
}
|
||||
|
||||
public boolean containsItem(String item) {
|
||||
return items.containsKey(item);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package mocks;
|
||||
|
||||
public class UtilityClass {
|
||||
public static String getMessage() {
|
||||
return "Original Message";
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package extensions
|
||||
|
||||
import mocks.ShoppingCart
|
||||
import spock.lang.Specification
|
||||
|
||||
class ShoppingCartTest extends Specification {
|
||||
def "verify multiple properties of a ShoppingCart"() {
|
||||
given:
|
||||
ShoppingCart cart = new ShoppingCart()
|
||||
cart.addItem("Apple", 3)
|
||||
cart.addItem("Banana", 2)
|
||||
|
||||
expect:
|
||||
with(cart) {
|
||||
totalItems == 5
|
||||
totalPrice == 10.00
|
||||
items.contains("Apple")
|
||||
items.contains("Banana")
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package mocks
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class BookServiceTest extends Specification {
|
||||
def "should retrieve book details and verify method calls"() {
|
||||
given:
|
||||
def bookRepository = Mock(BookRepository) {
|
||||
findById(1L) >> new Book("Effective Java", "Joshua Bloch")
|
||||
findById(2L) >> null
|
||||
}
|
||||
def bookService = new BookService(bookRepository)
|
||||
|
||||
when:
|
||||
Book effectiveJava = bookService.getBookDetails(1L)
|
||||
Book unknownBook = bookService.getBookDetails(2L)
|
||||
|
||||
then:
|
||||
1 * bookRepository.findById(1L)
|
||||
1 * bookRepository.findById(2L)
|
||||
effectiveJava.title == "Effective Java"
|
||||
unknownBook == null
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package mocks
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class MessageServiceTest extends Specification {
|
||||
def "should use global mock for UtilityClass"() {
|
||||
given:
|
||||
def utilityMock = GroovySpy(UtilityClass, global: true)
|
||||
utilityMock.getMessage() >> "Mocked Message"
|
||||
|
||||
when:
|
||||
MessageService service = new MessageService()
|
||||
String message = service.fetchMessage()
|
||||
|
||||
then:
|
||||
1 * utilityMock.getMessage()
|
||||
message == "Mocked Message"
|
||||
}
|
||||
}
|
@ -4,3 +4,5 @@ This module contains articles about (Timefold Solver)[https://timefold.ai].
|
||||
|
||||
### Relevant articles
|
||||
|
||||
- [A Guide to Timefold Solver for Employee Scheduling](https://www.baeldung.com/java-timefold-solver-guide)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user