Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-1525-Check-if-a-String-is-a-palindrome

This commit is contained in:
shouvikbhattacharya 2018-02-07 20:32:03 +05:30
commit 15ea8a7c01
18 changed files with 859 additions and 7 deletions

View File

@ -0,0 +1,52 @@
package com.baeldung.algorithms.maze.solver;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class BFSMazeSolver {
private static final int[][] DIRECTIONS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
public List<Coordinate> solve(Maze maze) {
LinkedList<Coordinate> nextToVisit = new LinkedList<>();
Coordinate start = maze.getEntry();
nextToVisit.add(start);
while (!nextToVisit.isEmpty()) {
Coordinate cur = nextToVisit.remove();
if (!maze.isValidLocation(cur.getX(), cur.getY()) || maze.isExplored(cur.getX(), cur.getY())) {
continue;
}
if (maze.isWall(cur.getX(), cur.getY())) {
maze.setVisited(cur.getX(), cur.getY(), true);
continue;
}
if (maze.isExit(cur.getX(), cur.getY())) {
return backtrackPath(cur);
}
for (int[] direction : DIRECTIONS) {
Coordinate coordinate = new Coordinate(cur.getX() + direction[0], cur.getY() + direction[1], cur);
nextToVisit.add(coordinate);
maze.setVisited(cur.getX(), cur.getY(), true);
}
}
return Collections.emptyList();
}
private List<Coordinate> backtrackPath(Coordinate cur) {
List<Coordinate> path = new ArrayList<>();
Coordinate iter = cur;
while (iter != null) {
path.add(iter);
iter = iter.parent;
}
return path;
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.algorithms.maze.solver;
public class Coordinate {
int x;
int y;
Coordinate parent;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
this.parent = null;
}
public Coordinate(int x, int y, Coordinate parent) {
this.x = x;
this.y = y;
this.parent = parent;
}
int getX() {
return x;
}
int getY() {
return y;
}
Coordinate getParent() {
return parent;
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.algorithms.maze.solver;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DFSMazeSolver {
private static final int[][] DIRECTIONS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
public List<Coordinate> solve(Maze maze) {
List<Coordinate> path = new ArrayList<>();
if (explore(maze, maze.getEntry()
.getX(),
maze.getEntry()
.getY(),
path)) {
return path;
}
return Collections.emptyList();
}
private boolean explore(Maze maze, int row, int col, List<Coordinate> path) {
if (!maze.isValidLocation(row, col) || maze.isWall(row, col) || maze.isExplored(row, col)) {
return false;
}
path.add(new Coordinate(row, col));
maze.setVisited(row, col, true);
if (maze.isExit(row, col)) {
return true;
}
for (int[] direction : DIRECTIONS) {
Coordinate coordinate = getNextCoordinate(row, col, direction[0], direction[1]);
if (explore(maze, coordinate.getX(), coordinate.getY(), path)) {
return true;
}
}
path.remove(path.size() - 1);
return false;
}
private Coordinate getNextCoordinate(int row, int col, int i, int j) {
return new Coordinate(row + i, col + j);
}
}

View File

@ -0,0 +1,141 @@
package com.baeldung.algorithms.maze.solver;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Maze {
private static final int ROAD = 0;
private static final int WALL = 1;
private static final int START = 2;
private static final int EXIT = 3;
private static final int PATH = 4;
private int[][] maze;
private boolean[][] visited;
private Coordinate start;
private Coordinate end;
public Maze(File maze) throws FileNotFoundException {
String fileText = "";
try (Scanner input = new Scanner(maze)) {
while (input.hasNextLine()) {
fileText += input.nextLine() + "\n";
}
}
initializeMaze(fileText);
}
private void initializeMaze(String text) {
if (text == null || (text = text.trim()).length() == 0) {
throw new IllegalArgumentException("empty lines data");
}
String[] lines = text.split("[\r]?\n");
maze = new int[lines.length][lines[0].length()];
visited = new boolean[lines.length][lines[0].length()];
for (int row = 0; row < getHeight(); row++) {
if (lines[row].length() != getWidth()) {
throw new IllegalArgumentException("line " + (row + 1) + " wrong length (was " + lines[row].length() + " but should be " + getWidth() + ")");
}
for (int col = 0; col < getWidth(); col++) {
if (lines[row].charAt(col) == '#')
maze[row][col] = WALL;
else if (lines[row].charAt(col) == 'S') {
maze[row][col] = START;
start = new Coordinate(row, col);
} else if (lines[row].charAt(col) == 'E') {
maze[row][col] = EXIT;
end = new Coordinate(row, col);
} else
maze[row][col] = ROAD;
}
}
}
public int getHeight() {
return maze.length;
}
public int getWidth() {
return maze[0].length;
}
public Coordinate getEntry() {
return start;
}
public Coordinate getExit() {
return end;
}
public boolean isExit(int x, int y) {
return x == end.getX() && y == end.getY();
}
public boolean isStart(int x, int y) {
return x == start.getX() && y == start.getY();
}
public boolean isExplored(int row, int col) {
return visited[row][col];
}
public boolean isWall(int row, int col) {
return maze[row][col] == WALL;
}
public void setVisited(int row, int col, boolean value) {
visited[row][col] = value;
}
public boolean isValidLocation(int row, int col) {
if (row < 0 || row >= getHeight() || col < 0 || col >= getWidth()) {
return false;
}
return true;
}
public void printPath(List<Coordinate> path) {
int[][] tempMaze = Arrays.stream(maze)
.map(int[]::clone)
.toArray(int[][]::new);
for (Coordinate coordinate : path) {
if (isStart(coordinate.getX(), coordinate.getY()) || isExit(coordinate.getX(), coordinate.getY())) {
continue;
}
tempMaze[coordinate.getX()][coordinate.getY()] = PATH;
}
System.out.println(toString(tempMaze));
}
public String toString(int[][] maze) {
StringBuilder result = new StringBuilder(getWidth() * (getHeight() + 1));
for (int row = 0; row < getHeight(); row++) {
for (int col = 0; col < getWidth(); col++) {
if (maze[row][col] == ROAD) {
result.append(' ');
} else if (maze[row][col] == WALL) {
result.append('#');
} else if (maze[row][col] == START) {
result.append('S');
} else if (maze[row][col] == EXIT) {
result.append('E');
} else {
result.append('.');
}
}
result.append('\n');
}
return result.toString();
}
public void reset() {
for (int i = 0; i < visited.length; i++)
Arrays.fill(visited[i], false);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.algorithms.maze.solver;
import java.io.File;
import java.util.List;
public class MazeDriver {
public static void main(String[] args) throws Exception {
File maze1 = new File("src/main/resources/maze/maze1.txt");
File maze2 = new File("src/main/resources/maze/maze2.txt");
execute(maze1);
execute(maze2);
}
private static void execute(File file) throws Exception {
Maze maze = new Maze(file);
dfs(maze);
bfs(maze);
}
private static void bfs(Maze maze) {
BFSMazeSolver bfs = new BFSMazeSolver();
List<Coordinate> path = bfs.solve(maze);
maze.printPath(path);
maze.reset();
}
private static void dfs(Maze maze) {
DFSMazeSolver dfs = new DFSMazeSolver();
List<Coordinate> path = dfs.solve(maze);
maze.printPath(path);
maze.reset();
}
}

View File

@ -0,0 +1,12 @@
S ########
# #
# ### ## #
# # # #
# # # # #
# ## #####
# # #
# # # # #
##### ####
# # E
# # # #
##########

View File

@ -0,0 +1,22 @@
S ##########################
# # # #
# # #### ############### #
# # # # # #
# # #### # # ###############
# # # # # # #
# # # #### ### ########### #
# # # # # #
# ################## #
######### # # # # #
# # #### # ####### # #
# # ### ### # # # # #
# # ## # ##### # #
##### ####### # # # # #
# # ## ## #### # #
# ##### ####### # #
# # ############
####### ######### # #
# # ######## #
# ####### ###### ## # E
# # # ## #
############################

View File

@ -18,7 +18,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.integration.version>4.3.5.RELEASE</spring.integration.version> <spring.version>5.0.1.RELEASE</spring.version>
<spring-social.version>1.1.4.RELEASE</spring-social.version> <spring-social.version>1.1.4.RELEASE</spring-social.version>
<javax-mail.version>1.4.7</javax-mail.version> <javax-mail.version>1.4.7</javax-mail.version>
<javax-activation.version>1.1.1</javax-activation.version> <javax-activation.version>1.1.1</javax-activation.version>
@ -68,7 +68,7 @@
<dependency> <dependency>
<groupId>org.springframework.integration</groupId> <groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId> <artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.activation</groupId> <groupId>javax.activation</groupId>
@ -84,17 +84,17 @@
<dependency> <dependency>
<groupId>org.springframework.integration</groupId> <groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-twitter</artifactId> <artifactId>spring-integration-twitter</artifactId>
<version>${spring.integration.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.integration</groupId> <groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mail</artifactId> <artifactId>spring-integration-mail</artifactId>
<version>${spring.integration.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.integration</groupId> <groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ftp</artifactId> <artifactId>spring-integration-ftp</artifactId>
<version>${spring.integration.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.social</groupId> <groupId>org.springframework.social</groupId>
@ -104,7 +104,36 @@
<dependency> <dependency>
<groupId>org.springframework.integration</groupId> <groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId> <artifactId>spring-integration-file</artifactId>
<version>${spring.integration.version}</version> <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-security</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>

View File

@ -0,0 +1,45 @@
package com.baeldung.si.security;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;
@Service
public class MessageConsumer {
private String messageContent;
private Map<String, String> messagePSContent = new ConcurrentHashMap<>();
public String getMessageContent() {
return messageContent;
}
public void setMessageContent(String messageContent) {
this.messageContent = messageContent;
}
public Map<String, String> getMessagePSContent() {
return messagePSContent;
}
public void setMessagePSContent(Map<String, String> messagePSContent) {
this.messagePSContent = messagePSContent;
}
@ServiceActivator(inputChannel = "endDirectChannel")
public void endDirectFlow(Message<?> message) {
setMessageContent(message.getPayload().toString());
}
@ServiceActivator(inputChannel = "finalPSResult")
public void endPSFlow(Message<?> message) {
Logger.getAnonymousLogger().info(Thread.currentThread().getName() + " has completed ---------------------------");
messagePSContent.put(Thread.currentThread().getName(), (String) message.getPayload());
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.si.security;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.security.channel.ChannelSecurityInterceptor;
import org.springframework.integration.security.channel.SecuredChannel;
import org.springframework.messaging.Message;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
@Configuration
@EnableIntegration
public class SecuredDirectChannel {
@Bean(name = "startDirectChannel")
@SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = { "ROLE_VIEWER", "jane" })
public DirectChannel startDirectChannel() {
return new DirectChannel();
}
@ServiceActivator(inputChannel = "startDirectChannel", outputChannel = "endDirectChannel")
@PreAuthorize("hasRole('ROLE_LOGGER')")
public Message<?> logMessage(Message<?> message) {
Logger.getAnonymousLogger().info(message.toString());
return message;
}
@Bean(name = "endDirectChannel")
@SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = { "ROLE_EDITOR" })
public DirectChannel endDirectChannel() {
return new DirectChannel();
}
@Autowired
@Bean
public ChannelSecurityInterceptor channelSecurityInterceptor(AuthenticationManager authenticationManager, AccessDecisionManager customAccessDecisionManager) {
ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor();
channelSecurityInterceptor.setAuthenticationManager(authenticationManager);
channelSecurityInterceptor.setAccessDecisionManager(customAccessDecisionManager);
return channelSecurityInterceptor;
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.si.security;
import java.util.ArrayList;
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.integration.security.channel.ChannelSecurityInterceptor;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Bean
public AccessDecisionManager customAccessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
decisionVoters.add(new RoleVoter());
decisionVoters.add(new UsernameAccessDecisionVoter());
AccessDecisionManager accessDecisionManager = new AffirmativeBased(decisionVoters);
return accessDecisionManager;
}
@Autowired
@Bean
public ChannelSecurityInterceptor channelSecurityInterceptor(AuthenticationManager authenticationManager, AccessDecisionManager customAccessDecisionManager) {
ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor();
channelSecurityInterceptor.setAuthenticationManager(authenticationManager);
channelSecurityInterceptor.setAccessDecisionManager(customAccessDecisionManager);
return channelSecurityInterceptor;
}
}

View File

@ -0,0 +1,82 @@
package com.baeldung.si.security;
import java.util.stream.Collectors;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.config.GlobalChannelInterceptor;
import org.springframework.integration.security.channel.SecuredChannel;
import org.springframework.integration.security.channel.SecurityContextPropagationChannelInterceptor;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@Configuration
@EnableIntegration
public class SecurityPubSubChannel {
@Bean(name = "startPSChannel")
@SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = "ROLE_VIEWER")
public PublishSubscribeChannel startChannel() {
return new PublishSubscribeChannel(executor());
}
@ServiceActivator(inputChannel = "startPSChannel", outputChannel = "finalPSResult")
@PreAuthorize("hasRole('ROLE_LOGGER')")
public Message<?> changeMessageToRole(Message<?> message) {
return buildNewMessage(getRoles(), message);
}
@ServiceActivator(inputChannel = "startPSChannel", outputChannel = "finalPSResult")
@PreAuthorize("hasRole('ROLE_VIEWER')")
public Message<?> changeMessageToUserName(Message<?> message) {
return buildNewMessage(getUsername(), message);
}
@Bean(name = "finalPSResult")
public DirectChannel finalPSResult() {
return new DirectChannel();
}
@Bean
@GlobalChannelInterceptor(patterns = { "startPSChannel", "endDirectChannel" })
public ChannelInterceptor securityContextPropagationInterceptor() {
return new SecurityContextPropagationChannelInterceptor();
}
@Bean
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(10);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}
public String getRoles() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return securityContext.getAuthentication().getAuthorities().stream().map(auth -> auth.getAuthority()).collect(Collectors.joining(","));
}
public String getUsername() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return securityContext.getAuthentication().getName();
}
public Message<String> buildNewMessage(String content, Message<?> message) {
DefaultMessageBuilderFactory builderFactory = new DefaultMessageBuilderFactory();
MessageBuilder<String> messageBuilder = builderFactory.withPayload(content);
messageBuilder.copyHeaders(message.getHeaders());
return messageBuilder.build();
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.si.security;
import java.util.Collection;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
public class UsernameAccessDecisionVoter implements AccessDecisionVoter<Object> {
private String rolePrefix = "ROLE_";
@Override
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null)
&& !attribute.getAttribute().startsWith(rolePrefix)) {
return true;
}else {
return false;
}
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
if (authentication == null) {
return ACCESS_DENIED;
}
String name = authentication.getName();
int result = ACCESS_ABSTAIN;
for (ConfigAttribute attribute : attributes) {
if (this.supports(attribute)) {
result = ACCESS_DENIED;
if (attribute.getAttribute().equals(name)) {
return ACCESS_GRANTED;
}
}
}
return result;
}
}

View File

@ -0,0 +1,81 @@
package com.baeldung.si;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.si.security.MessageConsumer;
import com.baeldung.si.security.SecuredDirectChannel;
import com.baeldung.si.security.SecurityConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { SecurityConfig.class, SecuredDirectChannel.class, MessageConsumer.class })
public class TestSpringIntegrationSecurity {
@Autowired
SubscribableChannel startDirectChannel;
@Autowired
MessageConsumer messageConsumer;
final String DIRECT_CHANNEL_MESSAGE = "Direct channel message";
@Test(expected = AuthenticationCredentialsNotFoundException.class)
public void givenNoUser_whenSendToDirectChannel_thenCredentialNotFound() {
startDirectChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
}
@Test(expected = AccessDeniedException.class)
@WithMockUser(username = "jane", roles = { "LOGGER" })
public void givenRoleLogger_whenSendMessageToDirectChannel_thenAccessDenied() throws Throwable {
try {
startDirectChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
} catch (Exception e) {
throw e.getCause();
}
}
@Test(expected = AccessDeniedException.class)
@WithMockUser(username = "jane")
public void givenJane_whenSendMessageToDirectChannel_thenAccessDenied() throws Throwable {
try {
startDirectChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
} catch (Exception e) {
throw e.getCause();
}
}
@Test(expected = AccessDeniedException.class)
@WithMockUser(roles = { "VIEWER" })
public void givenRoleViewer_whenSendToDirectChannel_thenAccessDenied() throws Throwable {
try {
startDirectChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
} catch (Exception e) {
throw e.getCause();
}
}
@Test
@WithMockUser(roles = { "LOGGER", "VIEWER", "EDITOR" })
public void givenRoleLoggerAndUser_whenSendMessageToDirectChannel_thenFlowCompletedSuccessfully() {
startDirectChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
assertEquals(DIRECT_CHANNEL_MESSAGE, messageConsumer.getMessageContent());
}
@Test
@WithMockUser(username = "jane", roles = { "LOGGER", "EDITOR" })
public void givenJaneLoggerEditor_whenSendToDirectChannel_thenFlowCompleted() {
startDirectChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
assertEquals(DIRECT_CHANNEL_MESSAGE, messageConsumer.getMessageContent());
}
}

View File

@ -0,0 +1,68 @@
package com.baeldung.si;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.baeldung.si.security.MessageConsumer;
import com.baeldung.si.security.SecurityConfig;
import com.baeldung.si.security.SecurityPubSubChannel;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { SecurityPubSubChannel.class, MessageConsumer.class, SecurityConfig.class })
public class TestSpringIntegrationSecurityExecutor {
@Autowired
SubscribableChannel startPSChannel;
@Autowired
MessageConsumer messageConsumer;
@Autowired
ThreadPoolTaskExecutor executor;
final String DIRECT_CHANNEL_MESSAGE = "Direct channel message";
@Before
public void clearData() {
messageConsumer.setMessagePSContent(new ConcurrentHashMap<>());
executor.setWaitForTasksToCompleteOnShutdown(true);
}
@Test
@WithMockUser(username = "user", roles = { "VIEWER" })
public void givenRoleUser_whenSendMessageToPSChannel_thenNoMessageArrived() throws IllegalStateException, InterruptedException {
startPSChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
executor.getThreadPoolExecutor().awaitTermination(2, TimeUnit.SECONDS);
assertEquals(1, messageConsumer.getMessagePSContent().size());
assertTrue(messageConsumer.getMessagePSContent().values().contains("user"));
}
@Test
@WithMockUser(username = "user", roles = { "LOGGER", "VIEWER" })
public void givenRoleUserAndLogger_whenSendMessageToPSChannel_then2GetMessages() throws IllegalStateException, InterruptedException {
startPSChannel.send(new GenericMessage<String>(DIRECT_CHANNEL_MESSAGE));
executor.getThreadPoolExecutor().awaitTermination(2, TimeUnit.SECONDS);
assertEquals(2, messageConsumer.getMessagePSContent().size());
assertTrue(messageConsumer.getMessagePSContent().values().contains("user"));
assertTrue(messageConsumer.getMessagePSContent().values().contains("ROLE_LOGGER,ROLE_VIEWER"));
}
}

View File

@ -173,7 +173,7 @@
<jacoco.version>0.7.7.201606060606</jacoco.version> <jacoco.version>0.7.7.201606060606</jacoco.version>
<guava.version>21.0</guava.version> <guava.version>21.0</guava.version>
<assertj-guava.version>3.1.0</assertj-guava.version> <assertj-guava.version>3.1.0</assertj-guava.version>
<assertj-core.version>3.6.1</assertj-core.version> <assertj-core.version>3.9.0</assertj-core.version>
<assertj-generator.version>2.1.0</assertj-generator.version> <assertj-generator.version>2.1.0</assertj-generator.version>
<truth.version>0.32</truth.version> <truth.version>0.32</truth.version>
<jUnitParams.version>1.1.0</jUnitParams.version> <jUnitParams.version>1.1.0</jUnitParams.version>

View File

@ -0,0 +1,24 @@
package com.baeldung.testing.assertj.exceptions;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import org.junit.Test;
public class Java7StyleAssertions {
@Test
public void whenDividingByZero_thenArithmeticException() {
try {
int numerator = 10;
int denominator = 0;
int quotient = numerator / denominator;
fail("ArithmeticException expected because dividing by zero yields an ArithmeticException.");
failBecauseExceptionWasNotThrown(ArithmeticException.class);
} catch (Exception e) {
assertThat(e).hasMessage("/ by zero");
assertThat(e).isInstanceOf(ArithmeticException.class);
}
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.testing.assertj.exceptions;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.catchThrowable;
import org.junit.Test;
public class Java8StyleAssertions {
@Test
public void whenDividingByZero_thenArithmeticException() {
assertThatThrownBy(() -> {
int numerator = 10;
int denominator = 0;
int quotient = numerator / denominator;
}).isInstanceOf(ArithmeticException.class)
.hasMessageContaining("/ by zero");
assertThatExceptionOfType(ArithmeticException.class).isThrownBy(() -> {
int numerator = 10;
int denominator = 0;
int quotient = numerator / denominator;
})
.withMessageContaining("/ by zero");
// BDD style:
// when
Throwable thrown = catchThrowable(() -> {
int numerator = 10;
int denominator = 0;
int quotient = numerator / denominator;
});
// then
assertThat(thrown).isInstanceOf(ArithmeticException.class)
.hasMessageContaining("/ by zero");
}
}