diff --git a/algorithms/src/main/java/com/baeldung/automata/FiniteStateMachine.java b/algorithms/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java similarity index 90% rename from algorithms/src/main/java/com/baeldung/automata/FiniteStateMachine.java rename to algorithms/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java index 943b44fe05..0cb11f5138 100644 --- a/algorithms/src/main/java/com/baeldung/automata/FiniteStateMachine.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java @@ -1,4 +1,4 @@ -package com.baeldung.automata; +package com.baeldung.algorithms.automata; /** * Finite state machine. diff --git a/algorithms/src/main/java/com/baeldung/automata/RtFiniteStateMachine.java b/algorithms/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java similarity index 93% rename from algorithms/src/main/java/com/baeldung/automata/RtFiniteStateMachine.java rename to algorithms/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java index 090e00c73c..1cf06c04b5 100644 --- a/algorithms/src/main/java/com/baeldung/automata/RtFiniteStateMachine.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java @@ -1,4 +1,4 @@ -package com.baeldung.automata; +package com.baeldung.algorithms.automata; /** * Default implementation of a finite state machine. diff --git a/algorithms/src/main/java/com/baeldung/automata/RtState.java b/algorithms/src/main/java/com/baeldung/algorithms/automata/RtState.java similarity index 95% rename from algorithms/src/main/java/com/baeldung/automata/RtState.java rename to algorithms/src/main/java/com/baeldung/algorithms/automata/RtState.java index b4a5df7961..31cb9b577e 100644 --- a/algorithms/src/main/java/com/baeldung/automata/RtState.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/automata/RtState.java @@ -1,4 +1,4 @@ -package com.baeldung.automata; +package com.baeldung.algorithms.automata; import java.util.ArrayList; import java.util.List; diff --git a/algorithms/src/main/java/com/baeldung/automata/RtTransition.java b/algorithms/src/main/java/com/baeldung/algorithms/automata/RtTransition.java similarity index 93% rename from algorithms/src/main/java/com/baeldung/automata/RtTransition.java rename to algorithms/src/main/java/com/baeldung/algorithms/automata/RtTransition.java index 560011e42a..cb205deacb 100644 --- a/algorithms/src/main/java/com/baeldung/automata/RtTransition.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/automata/RtTransition.java @@ -1,4 +1,4 @@ -package com.baeldung.automata; +package com.baeldung.algorithms.automata; /** diff --git a/algorithms/src/main/java/com/baeldung/automata/State.java b/algorithms/src/main/java/com/baeldung/algorithms/automata/State.java similarity index 93% rename from algorithms/src/main/java/com/baeldung/automata/State.java rename to algorithms/src/main/java/com/baeldung/algorithms/automata/State.java index a25af9d03a..1889c4c7f6 100644 --- a/algorithms/src/main/java/com/baeldung/automata/State.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/automata/State.java @@ -1,4 +1,4 @@ -package com.baeldung.automata; +package com.baeldung.algorithms.automata; /** * State. Part of a finite state machine. diff --git a/algorithms/src/main/java/com/baeldung/automata/Transition.java b/algorithms/src/main/java/com/baeldung/algorithms/automata/Transition.java similarity index 89% rename from algorithms/src/main/java/com/baeldung/automata/Transition.java rename to algorithms/src/main/java/com/baeldung/algorithms/automata/Transition.java index d57620f911..68177ba7dd 100644 --- a/algorithms/src/main/java/com/baeldung/automata/Transition.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/automata/Transition.java @@ -1,4 +1,4 @@ -package com.baeldung.automata; +package com.baeldung.algorithms.automata; /** * Transition in a finite State machine. diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java new file mode 100644 index 0000000000..f428df45d3 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java @@ -0,0 +1,109 @@ +package com.baeldung.algorithms.mcts.montecarlo; + +import java.util.List; + +import com.baeldung.algorithms.mcts.tictactoe.Board; +import com.baeldung.algorithms.mcts.tree.Node; +import com.baeldung.algorithms.mcts.tree.Tree; + +public class MonteCarloTreeSearch { + + private static final int WIN_SCORE = 10; + private int level; + private int oponent; + + public MonteCarloTreeSearch() { + this.level = 3; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + private int getMillisForCurrentLevel() { + return 2 * (this.level - 1) + 1; + } + + public Board findNextMove(Board board, int playerNo) { + long start = System.currentTimeMillis(); + long end = start + 60 * getMillisForCurrentLevel(); + + oponent = 3 - playerNo; + Tree tree = new Tree(); + Node rootNode = tree.getRoot(); + rootNode.getState().setBoard(board); + rootNode.getState().setPlayerNo(oponent); + + while (System.currentTimeMillis() < end) { + // Phase 1 - Selection + Node promisingNode = selectPromisingNode(rootNode); + // Phase 2 - Expansion + if (promisingNode.getState().getBoard().checkStatus() == Board.IN_PROGRESS) + expandNode(promisingNode); + + // Phase 3 - Simulation + Node nodeToExplore = promisingNode; + if (promisingNode.getChildArray().size() > 0) { + nodeToExplore = promisingNode.getRandomChildNode(); + } + int playoutResult = simulateRandomPlayout(nodeToExplore); + // Phase 4 - Update + backPropogation(nodeToExplore, playoutResult); + } + + Node winnerNode = rootNode.getChildWithMaxScore(); + tree.setRoot(winnerNode); + return winnerNode.getState().getBoard(); + } + + private Node selectPromisingNode(Node rootNode) { + Node node = rootNode; + while (node.getChildArray().size() != 0) { + node = UCT.findBestNodeWithUCT(node); + } + return node; + } + + private void expandNode(Node node) { + List possibleStates = node.getState().getAllPossibleStates(); + possibleStates.forEach(state -> { + Node newNode = new Node(state); + newNode.setParent(node); + newNode.getState().setPlayerNo(node.getState().getOpponent()); + node.getChildArray().add(newNode); + }); + } + + private void backPropogation(Node nodeToExplore, int playerNo) { + Node tempNode = nodeToExplore; + while (tempNode != null) { + tempNode.getState().incrementVisit(); + if (tempNode.getState().getPlayerNo() == playerNo) + tempNode.getState().addScore(WIN_SCORE); + tempNode = tempNode.getParent(); + } + } + + private int simulateRandomPlayout(Node node) { + Node tempNode = new Node(node); + State tempState = tempNode.getState(); + int boardStatus = tempState.getBoard().checkStatus(); + + if (boardStatus == oponent) { + tempNode.getParent().getState().setWinScore(Integer.MIN_VALUE); + return boardStatus; + } + while (boardStatus == Board.IN_PROGRESS) { + tempState.togglePlayer(); + tempState.randomPlay(); + boardStatus = tempState.getBoard().checkStatus(); + } + + return boardStatus; + } + +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java new file mode 100644 index 0000000000..d855f775a8 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java @@ -0,0 +1,97 @@ +package com.baeldung.algorithms.mcts.montecarlo; + +import java.util.ArrayList; +import java.util.List; + +import com.baeldung.algorithms.mcts.tictactoe.Board; +import com.baeldung.algorithms.mcts.tictactoe.Position; + +public class State { + private Board board; + private int playerNo; + private int visitCount; + private double winScore; + + public State() { + board = new Board(); + } + + public State(State state) { + this.board = new Board(state.getBoard()); + this.playerNo = state.getPlayerNo(); + this.visitCount = state.getVisitCount(); + this.winScore = state.getWinScore(); + } + + public State(Board board) { + this.board = new Board(board); + } + + Board getBoard() { + return board; + } + + void setBoard(Board board) { + this.board = board; + } + + int getPlayerNo() { + return playerNo; + } + + void setPlayerNo(int playerNo) { + this.playerNo = playerNo; + } + + int getOpponent() { + return 3 - playerNo; + } + + public int getVisitCount() { + return visitCount; + } + + public void setVisitCount(int visitCount) { + this.visitCount = visitCount; + } + + double getWinScore() { + return winScore; + } + + void setWinScore(double winScore) { + this.winScore = winScore; + } + + public List getAllPossibleStates() { + List possibleStates = new ArrayList<>(); + List availablePositions = this.board.getEmptyPositions(); + availablePositions.forEach(p -> { + State newState = new State(this.board); + newState.setPlayerNo(3 - this.playerNo); + newState.getBoard().performMove(newState.getPlayerNo(), p); + possibleStates.add(newState); + }); + return possibleStates; + } + + void incrementVisit() { + this.visitCount++; + } + + void addScore(double score) { + if (this.winScore != Integer.MIN_VALUE) + this.winScore += score; + } + + void randomPlay() { + List availablePositions = this.board.getEmptyPositions(); + int totalPossibilities = availablePositions.size(); + int selectRandom = (int) (Math.random() * ((totalPossibilities - 1) + 1)); + this.board.performMove(this.playerNo, availablePositions.get(selectRandom)); + } + + void togglePlayer() { + this.playerNo = 3 - this.playerNo; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java new file mode 100644 index 0000000000..52707aab55 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java @@ -0,0 +1,24 @@ +package com.baeldung.algorithms.mcts.montecarlo; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.baeldung.algorithms.mcts.tree.Node; + +public class UCT { + + public static double uctValue(int totalVisit, double nodeWinScore, int nodeVisit) { + if (nodeVisit == 0) { + return Integer.MAX_VALUE; + } + return (nodeWinScore / (double) nodeVisit) + 1.41 * Math.sqrt(Math.log(totalVisit) / (double) nodeVisit); + } + + static Node findBestNodeWithUCT(Node node) { + int parentVisit = node.getState().getVisitCount(); + return Collections.max( + node.getChildArray(), + Comparator.comparing(c -> uctValue(parentVisit, c.getState().getWinScore(), c.getState().getVisitCount()))); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java new file mode 100644 index 0000000000..8b47fa0fdf --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java @@ -0,0 +1,155 @@ +package com.baeldung.algorithms.mcts.tictactoe; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Board { + int[][] boardValues; + int totalMoves; + + public static final int DEFAULT_BOARD_SIZE = 3; + + public static final int IN_PROGRESS = -1; + public static final int DRAW = 0; + public static final int P1 = 1; + public static final int P2 = 2; + + public Board() { + boardValues = new int[DEFAULT_BOARD_SIZE][DEFAULT_BOARD_SIZE]; + } + + public Board(int boardSize) { + boardValues = new int[boardSize][boardSize]; + } + + public Board(int[][] boardValues) { + this.boardValues = boardValues; + } + + public Board(int[][] boardValues, int totalMoves) { + this.boardValues = boardValues; + this.totalMoves = totalMoves; + } + + public Board(Board board) { + int boardLength = board.getBoardValues().length; + this.boardValues = new int[boardLength][boardLength]; + int[][] boardValues = board.getBoardValues(); + int n = boardValues.length; + for (int i = 0; i < n; i++) { + int m = boardValues[i].length; + for (int j = 0; j < m; j++) { + this.boardValues[i][j] = boardValues[i][j]; + } + } + } + + public void performMove(int player, Position p) { + this.totalMoves++; + boardValues[p.getX()][p.getY()] = player; + } + + public int[][] getBoardValues() { + return boardValues; + } + + public void setBoardValues(int[][] boardValues) { + this.boardValues = boardValues; + } + + public int checkStatus() { + int boardSize = boardValues.length; + int maxIndex = boardSize - 1; + int[] diag1 = new int[boardSize]; + int[] diag2 = new int[boardSize]; + + for (int i = 0; i < boardSize; i++) { + int[] row = boardValues[i]; + int[] col = new int[boardSize]; + for (int j = 0; j < boardSize; j++) { + col[j] = boardValues[j][i]; + } + + int checkRowForWin = checkForWin(row); + if(checkRowForWin!=0) + return checkRowForWin; + + int checkColForWin = checkForWin(col); + if(checkColForWin!=0) + return checkColForWin; + + diag1[i] = boardValues[i][i]; + diag2[i] = boardValues[maxIndex - i][i]; + } + + int checkDia1gForWin = checkForWin(diag1); + if(checkDia1gForWin!=0) + return checkDia1gForWin; + + int checkDiag2ForWin = checkForWin(diag2); + if(checkDiag2ForWin!=0) + return checkDiag2ForWin; + + if (getEmptyPositions().size() > 0) + return IN_PROGRESS; + else + return DRAW; + } + + private int checkForWin(int[] row) { + boolean isEqual = true; + int size = row.length; + int previous = row[0]; + for (int i = 0; i < size; i++) { + if (previous != row[i]) { + isEqual = false; + break; + } + previous = row[i]; + } + if(isEqual) + return previous; + else + return 0; + } + + public void printBoard() { + int size = this.boardValues.length; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + System.out.print(boardValues[i][j] + " "); + } + System.out.println(); + } + } + + public List getEmptyPositions() { + int size = this.boardValues.length; + List emptyPositions = new ArrayList<>(); + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (boardValues[i][j] == 0) + emptyPositions.add(new Position(i, j)); + } + } + return emptyPositions; + } + + public void printStatus() { + switch (this.checkStatus()) { + case P1: + System.out.println("Player 1 wins"); + break; + case P2: + System.out.println("Player 2 wins"); + break; + case DRAW: + System.out.println("Game Draw"); + break; + case IN_PROGRESS: + System.out.println("Game In rogress"); + break; + } + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java new file mode 100644 index 0000000000..94ead4288d --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java @@ -0,0 +1,31 @@ +package com.baeldung.algorithms.mcts.tictactoe; + +public class Position { + int x; + int y; + + public Position() { + } + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java new file mode 100644 index 0000000000..20f9e992b5 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java @@ -0,0 +1,78 @@ +package com.baeldung.algorithms.mcts.tree; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.baeldung.algorithms.mcts.montecarlo.State; + +public class Node { + State state; + Node parent; + List childArray; + + public Node() { + this.state = new State(); + childArray = new ArrayList<>(); + } + + public Node(State state) { + this.state = state; + childArray = new ArrayList<>(); + } + + public Node(State state, Node parent, List childArray) { + this.state = state; + this.parent = parent; + this.childArray = childArray; + } + + public Node(Node node) { + this.childArray = new ArrayList<>(); + this.state = new State(node.getState()); + if (node.getParent() != null) + this.parent = node.getParent(); + List childArray = node.getChildArray(); + for (Node child : childArray) { + this.childArray.add(new Node(child)); + } + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public Node getParent() { + return parent; + } + + public void setParent(Node parent) { + this.parent = parent; + } + + public List getChildArray() { + return childArray; + } + + public void setChildArray(List childArray) { + this.childArray = childArray; + } + + public Node getRandomChildNode() { + int noOfPossibleMoves = this.childArray.size(); + int selectRandom = (int) (Math.random() * ((noOfPossibleMoves - 1) + 1)); + return this.childArray.get(selectRandom); + } + + public Node getChildWithMaxScore() { + return Collections.max(this.childArray, Comparator.comparing(c -> { + return c.getState().getVisitCount(); + })); + } + +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java new file mode 100644 index 0000000000..c5543c0ed4 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.mcts.tree; + +public class Tree { + Node root; + + public Tree() { + root = new Node(); + } + + public Tree(Node root) { + this.root = root; + } + + public Node getRoot() { + return root; + } + + public void setRoot(Node root) { + this.root = root; + } + + public void addChild(Node parent, Node child) { + parent.getChildArray().add(child); + } + +} diff --git a/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java b/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java index c6800e9a64..99e962773f 100644 --- a/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java +++ b/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java @@ -1,6 +1,6 @@ package algorithms; -import com.baeldung.automata.*; +import com.baeldung.algorithms.automata.*; import org.junit.Test; import static org.junit.Assert.assertTrue; diff --git a/algorithms/src/test/java/algorithms/mcts/MCTSTest.java b/algorithms/src/test/java/algorithms/mcts/MCTSTest.java new file mode 100644 index 0000000000..375f66ab6f --- /dev/null +++ b/algorithms/src/test/java/algorithms/mcts/MCTSTest.java @@ -0,0 +1,92 @@ +package algorithms.mcts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.algorithms.mcts.montecarlo.MonteCarloTreeSearch; +import com.baeldung.algorithms.mcts.montecarlo.State; +import com.baeldung.algorithms.mcts.montecarlo.UCT; +import com.baeldung.algorithms.mcts.tictactoe.Board; +import com.baeldung.algorithms.mcts.tictactoe.Position; +import com.baeldung.algorithms.mcts.tree.Tree; + +public class MCTSTest { + private Tree gameTree; + private MonteCarloTreeSearch mcts; + + @Before + public void initGameTree() { + gameTree = new Tree(); + mcts = new MonteCarloTreeSearch(); + } + + @Test + public void givenStats_whenGetUCTForNode_thenUCTMatchesWithManualData() { + double uctValue = 15.79; + assertEquals(UCT.uctValue(600, 300, 20), uctValue, 0.01); + } + + @Test + public void giveninitBoardState_whenGetAllPossibleStates_thenNonEmptyList() { + State initState = gameTree.getRoot().getState(); + List possibleStates = initState.getAllPossibleStates(); + assertTrue(possibleStates.size() > 0); + } + + @Test + public void givenEmptyBoard_whenPerformMove_thenLessAvailablePossitions() { + Board board = new Board(); + int initAvailablePositions = board.getEmptyPositions().size(); + board.performMove(Board.P1, new Position(1, 1)); + int availablePositions = board.getEmptyPositions().size(); + assertTrue(initAvailablePositions > availablePositions); + } + + @Test + public void givenEmptyBoard_whenSimulateInterAIPlay_thenGameDraw() { + Board board = new Board(); + + int player = Board.P1; + int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE; + for (int i = 0; i < totalMoves; i++) { + board = mcts.findNextMove(board, player); + if (board.checkStatus() != -1) { + break; + } + player = 3 - player; + } + int winStatus = board.checkStatus(); + assertEquals(winStatus, Board.DRAW); + } + + @Test + public void givenEmptyBoard_whenLevel1VsLevel3_thenLevel3WinsOrDraw() { + Board board = new Board(); + MonteCarloTreeSearch mcts1 = new MonteCarloTreeSearch(); + mcts1.setLevel(1); + MonteCarloTreeSearch mcts3 = new MonteCarloTreeSearch(); + mcts3.setLevel(3); + + int player = Board.P1; + int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE; + for (int i = 0; i < totalMoves; i++) { + if (player == Board.P1) + board = mcts3.findNextMove(board, player); + else + board = mcts1.findNextMove(board, player); + + if (board.checkStatus() != -1) { + break; + } + player = 3 - player; + } + int winStatus = board.checkStatus(); + assertTrue(winStatus == Board.DRAW || winStatus == Board.P1); + } + +} diff --git a/core-java/src/main/java/com/baeldung/javanetworking/url/URLDemo.java b/core-java/src/main/java/com/baeldung/javanetworking/url/URLDemo.java new file mode 100644 index 0000000000..f8038a7e86 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/javanetworking/url/URLDemo.java @@ -0,0 +1,69 @@ +package com.baeldung.javanetworking.url; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class URLDemo { + private final Logger log = LoggerFactory.getLogger(URLDemo.class); + + String URLSTRING = "https://wordpress.org:443/support/topic/page-jumps-within-wordpress/?replies=3#post-2278484"; + // parsed locator + String URLPROTOCOL = "https"; + // final static String URLAUTHORITY = "wordpress.org:443"; + String URLHOST = "wordpress.org"; + String URLPATH = "/support/topic/page-jumps-within-wordpress/"; + // final static String URLFILENAME = "/support/topic/page-jumps-within-wordpress/?replies=3"; + // final static int URLPORT = 443; + int URLDEFAULTPORT = 443; + String URLQUERY = "replies=3"; + String URLREFERENCE = "post-2278484"; + String URLCOMPOUND = URLPROTOCOL + "://" + URLHOST + ":" + URLDEFAULTPORT + URLPATH + "?" + URLQUERY + "#" + URLREFERENCE; + + URL url; + URLConnection urlConnection = null; + HttpURLConnection connection = null; + BufferedReader in = null; + String urlContent = ""; + + public String testURL(String urlString) throws IOException, IllegalArgumentException { + String urlStringCont = ""; + // comment the if clause if experiment with URL + /*if (!URLSTRING.equals(urlString)) { + throw new IllegalArgumentException("URL String argument is not proper: " + urlString); + }*/ + // creating URL object + url = new URL(urlString); + // get URL connection + urlConnection = url.openConnection(); + connection = null; + // we can check, if connection is proper type + if (urlConnection instanceof HttpURLConnection) { + connection = (HttpURLConnection) urlConnection; + } else { + log.info("Please enter an HTTP URL"); + throw new IOException("HTTP URL is not correct"); + } + // we can check response code (200 OK is expected) + log.info(connection.getResponseCode() + " " + connection.getResponseMessage()); + in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String current; + + while ((current = in.readLine()) != null) { + urlStringCont += current; + } + return urlStringCont; + } + + public static void main(String[] args) throws Exception { + URLDemo demo = new URLDemo(); + String content = demo.testURL(demo.URLCOMPOUND); + demo.log.info(content); + } +} diff --git a/core-java/src/main/java/log4j.properties b/core-java/src/main/java/log4j.properties new file mode 100644 index 0000000000..5fe42d854c --- /dev/null +++ b/core-java/src/main/java/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, A1 + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n diff --git a/core-java/src/test/java/com/baeldung/javanetworking/url/test/URLDemoTest.java b/core-java/src/test/java/com/baeldung/javanetworking/url/test/URLDemoTest.java new file mode 100644 index 0000000000..293052e842 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/javanetworking/url/test/URLDemoTest.java @@ -0,0 +1,106 @@ +package com.baeldung.javanetworking.url.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.baeldung.javanetworking.url.URLDemo; + +@FixMethodOrder +public class URLDemoTest { + private final Logger log = LoggerFactory.getLogger(URLDemo.class); + static String URLSTRING = "https://wordpress.org:443/support/topic/page-jumps-within-wordpress/?replies=3#post-2278484"; + // parsed locator + static String URLPROTOCOL = "https"; + String URLAUTHORITY = "wordpress.org:443"; + static String URLHOST = "wordpress.org"; + static String URLPATH = "/support/topic/page-jumps-within-wordpress/"; + String URLFILENAME = "/support/topic/page-jumps-within-wordpress/?replies=3"; + int URLPORT = 443; + static int URLDEFAULTPORT = 443; + static String URLQUERY = "replies=3"; + static String URLREFERENCE = "post-2278484"; + static String URLCOMPOUND = URLPROTOCOL + "://" + URLHOST + ":" + URLDEFAULTPORT + URLPATH + "?" + URLQUERY + "#" + URLREFERENCE; + + static URL url; + URLConnection urlConnection = null; + HttpURLConnection connection = null; + BufferedReader in = null; + String urlContent = ""; + + @BeforeClass + public static void givenEmplyURL_whenInitializeURL_thenSuccess() throws MalformedURLException { + url = new URL(URLCOMPOUND); + } + + // check parsed URL + @Test + public void givenURL_whenURLIsParsed_thenSuccess() { + assertNotNull("URL is null", url); + assertEquals("URL string is not equal", url.toString(), URLSTRING); + assertEquals("Protocol is not equal", url.getProtocol(), URLPROTOCOL); + assertEquals("Authority is not equal", url.getAuthority(), URLAUTHORITY); + assertEquals("Host string is not equal", url.getHost(), URLHOST); + assertEquals("Path string is not equal", url.getPath(), URLPATH); + assertEquals("File string is not equal", url.getFile(), URLFILENAME); + assertEquals("Port number is not equal", url.getPort(), URLPORT); + assertEquals("Default port number is not equal", url.getDefaultPort(), URLDEFAULTPORT); + assertEquals("Query string is not equal", url.getQuery(), URLQUERY); + assertEquals("Reference string is not equal", url.getRef(), URLREFERENCE); + } + + // Obtain the content from location + @Test + public void givenURL_whenOpenConnectionAndContentIsNotEmpty_thenSuccess() throws IOException { + try { + urlConnection = url.openConnection(); + } catch (IOException ex) { + urlConnection = null; + ex.printStackTrace(); + } + assertNotNull("URL Connection is null", urlConnection); + + connection = null; + assertTrue("URLConnection is not HttpURLConnection", urlConnection instanceof HttpURLConnection); + if (urlConnection instanceof HttpURLConnection) { + connection = (HttpURLConnection) urlConnection; + } + assertNotNull("Connection is null", connection); + + log.info(connection.getResponseCode() + " " + connection.getResponseMessage()); + + try { + in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + } catch (IOException ex) { + in = null; + ex.printStackTrace(); + } + assertNotNull("Input stream failed", in); + + String current; + try { + while ((current = in.readLine()) != null) { + urlContent += current; + } + } catch (IOException ex) { + urlContent = null; + ex.printStackTrace(); + } + assertNotNull("Content is null", urlContent); + assertTrue("Content is empty", urlContent.length() > 0); + } +} diff --git a/drools/README.MD b/drools/README.MD new file mode 100644 index 0000000000..4ece7608fc --- /dev/null +++ b/drools/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles: +[Introduction to Drools](http://www.baeldung.com/drools) +[Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel) diff --git a/drools/pom.xml b/drools/pom.xml index b352044fb8..29231f150c 100644 --- a/drools/pom.xml +++ b/drools/pom.xml @@ -16,7 +16,7 @@ 4.4.6 - 7.0.0.CR1 + 7.1.0.Beta2 3.13 diff --git a/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java b/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java index 5f0d619813..e8841b05e2 100644 --- a/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java +++ b/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java @@ -1,10 +1,15 @@ package com.baeldung.drools.config; +import org.drools.decisiontable.DecisionTableProviderImpl; import org.kie.api.KieServices; import org.kie.api.builder.*; import org.kie.api.io.KieResources; +import org.kie.api.io.Resource; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; +import org.kie.internal.builder.DecisionTableConfiguration; +import org.kie.internal.builder.DecisionTableInputType; +import org.kie.internal.builder.KnowledgeBuilderFactory; import org.kie.internal.io.ResourceFactory; import java.io.IOException; import java.util.Arrays; @@ -64,4 +69,39 @@ public class DroolsBeanFactory { } -} \ No newline at end of file + public KieSession getKieSession(Resource dt) { + KieFileSystem kieFileSystem = kieServices.newKieFileSystem() + .write(dt); + + KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem) + .buildAll(); + + KieRepository kieRepository = kieServices.getRepository(); + + ReleaseId krDefaultReleaseId = kieRepository.getDefaultReleaseId(); + + KieContainer kieContainer = kieServices.newKieContainer(krDefaultReleaseId); + + KieSession ksession = kieContainer.newKieSession(); + + return ksession; + } + + /* + * Can be used for debugging + * Input excelFile example: com/baeldung/drools/rules/Discount.xls + */ + public String getDrlFromExcel(String excelFile) { + DecisionTableConfiguration configuration = KnowledgeBuilderFactory.newDecisionTableConfiguration(); + configuration.setInputType(DecisionTableInputType.XLS); + + Resource dt = ResourceFactory.newClassPathResource(excelFile, getClass()); + + DecisionTableProviderImpl decisionTableProvider = new DecisionTableProviderImpl(); + + String drl = decisionTableProvider.loadFromResource(dt, null); + + return drl; + } + +} diff --git a/drools/src/main/java/com/baeldung/drools/model/Customer.java b/drools/src/main/java/com/baeldung/drools/model/Customer.java new file mode 100644 index 0000000000..e900612b55 --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/model/Customer.java @@ -0,0 +1,44 @@ +package com.baeldung.drools.model; + +public class Customer { + + private CustomerType type; + + private int years; + + private int discount; + + public Customer(CustomerType type, int numOfYears) { + super(); + this.type = type; + this.years = numOfYears; + } + + public CustomerType getType() { + return type; + } + + public void setType(CustomerType type) { + this.type = type; + } + + public int getYears() { + return years; + } + + public void setYears(int years) { + this.years = years; + } + + public int getDiscount() { + return discount; + } + + public void setDiscount(int discount) { + this.discount = discount; + } + + public enum CustomerType { + INDIVIDUAL, BUSINESS; + } +} diff --git a/drools/src/main/resources/com/baeldung/drools/rules/Discount.xls b/drools/src/main/resources/com/baeldung/drools/rules/Discount.xls new file mode 100644 index 0000000000..198cc8dcda Binary files /dev/null and b/drools/src/main/resources/com/baeldung/drools/rules/Discount.xls differ diff --git a/drools/src/test/java/com/baeldung/drools/service/ApplicantServiceIntegrationTest.java b/drools/src/test/java/com/baeldung/drools/service/ApplicantServiceIntegrationTest.java index 71f33f2db4..f5d74c0a58 100644 --- a/drools/src/test/java/com/baeldung/drools/service/ApplicantServiceIntegrationTest.java +++ b/drools/src/test/java/com/baeldung/drools/service/ApplicantServiceIntegrationTest.java @@ -17,37 +17,39 @@ public class ApplicantServiceIntegrationTest { private ApplicantService applicantService; @Before - public void setup(){ + public void setup() { applicantService = new ApplicantService(); } @Test public void whenCriteriaMatching_ThenSuggestManagerRole() throws IOException { - Applicant applicant=new Applicant("Davis",37,1600000.0,11); - SuggestedRole suggestedRole=new SuggestedRole(); - applicantService.suggestARoleForApplicant(applicant,suggestedRole); - assertEquals("Manager",suggestedRole.getRole()); + Applicant applicant = new Applicant("Davis", 37, 1600000.0, 11); + SuggestedRole suggestedRole = new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant, suggestedRole); + assertEquals("Manager", suggestedRole.getRole()); } @Test public void whenCriteriaMatching_ThenSuggestSeniorDeveloperRole() throws IOException { - Applicant applicant=new Applicant("John",37,1200000.0,8); - SuggestedRole suggestedRole=new SuggestedRole(); - applicantService.suggestARoleForApplicant(applicant,suggestedRole); - assertEquals("Senior developer",suggestedRole.getRole()); + Applicant applicant = new Applicant("John", 37, 1200000.0, 8); + SuggestedRole suggestedRole = new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant, suggestedRole); + assertEquals("Senior developer", suggestedRole.getRole()); } + @Test public void whenCriteriaMatching_ThenSuggestDeveloperRole() throws IOException { - Applicant applicant=new Applicant("Davis",37,800000.0,3); - SuggestedRole suggestedRole=new SuggestedRole(); - applicantService.suggestARoleForApplicant(applicant,suggestedRole); - assertEquals("Developer",suggestedRole.getRole()); + Applicant applicant = new Applicant("Davis", 37, 800000.0, 3); + SuggestedRole suggestedRole = new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant, suggestedRole); + assertEquals("Developer", suggestedRole.getRole()); } + @Test public void whenCriteriaNotMatching_ThenNoRole() throws IOException { - Applicant applicant=new Applicant("John",37,1200000.0,5); - SuggestedRole suggestedRole=new SuggestedRole(); - applicantService.suggestARoleForApplicant(applicant,suggestedRole); + Applicant applicant = new Applicant("John", 37, 1200000.0, 5); + SuggestedRole suggestedRole = new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant, suggestedRole); assertNull(suggestedRole.getRole()); } } diff --git a/drools/src/test/java/com/baeldung/drools/service/DiscountExcelIntegrationTest.java b/drools/src/test/java/com/baeldung/drools/service/DiscountExcelIntegrationTest.java new file mode 100644 index 0000000000..c3c4ebd4f8 --- /dev/null +++ b/drools/src/test/java/com/baeldung/drools/service/DiscountExcelIntegrationTest.java @@ -0,0 +1,56 @@ +package com.baeldung.drools.service; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; +import org.kie.api.io.Resource; +import org.kie.api.runtime.KieSession; +import org.kie.internal.io.ResourceFactory; + +import com.baeldung.drools.config.DroolsBeanFactory; +import com.baeldung.drools.model.Customer; +import com.baeldung.drools.model.Customer.CustomerType; + +public class DiscountExcelIntegrationTest { + + private KieSession kSession; + + @Before + public void setup() { + Resource resource = ResourceFactory.newClassPathResource("com/baeldung/drools/rules/Discount.xls", getClass()); + kSession = new DroolsBeanFactory().getKieSession(resource); + } + + @Test + public void giveIndvidualLongStanding_whenFireRule_thenCorrectDiscount() throws Exception { + Customer customer = new Customer(CustomerType.INDIVIDUAL, 5); + kSession.insert(customer); + + kSession.fireAllRules(); + + assertEquals(customer.getDiscount(), 15); + } + + @Test + public void giveIndvidualRecent_whenFireRule_thenCorrectDiscount() throws Exception { + + Customer customer = new Customer(CustomerType.INDIVIDUAL, 1); + kSession.insert(customer); + + kSession.fireAllRules(); + + assertEquals(customer.getDiscount(), 5); + } + + @Test + public void giveBusinessAny_whenFireRule_thenCorrectDiscount() throws Exception { + Customer customer = new Customer(CustomerType.BUSINESS, 0); + kSession.insert(customer); + + kSession.fireAllRules(); + + assertEquals(customer.getDiscount(), 20); + } + +} diff --git a/drools/src/test/java/com/baeldung/drools/service/ProductServiceIntegrationTest.java b/drools/src/test/java/com/baeldung/drools/service/ProductServiceIntegrationTest.java index 08c3fceb7d..73624c2c99 100644 --- a/drools/src/test/java/com/baeldung/drools/service/ProductServiceIntegrationTest.java +++ b/drools/src/test/java/com/baeldung/drools/service/ProductServiceIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung.drools.service; import com.baeldung.drools.model.Product; import org.junit.Before; import org.junit.Test; + import static junit.framework.TestCase.assertEquals; @@ -11,22 +12,22 @@ public class ProductServiceIntegrationTest { private ProductService productService; @Before - public void setup(){ - productService=new ProductService(); + public void setup() { + productService = new ProductService(); } @Test - public void whenProductTypeElectronic_ThenLabelBarcode(){ - Product product=new Product("Microwave","Electronic"); - product=productService.applyLabelToProduct(product); - assertEquals("BarCode",product.getLabel()); + public void whenProductTypeElectronic_ThenLabelBarcode() { + Product product = new Product("Microwave", "Electronic"); + product = productService.applyLabelToProduct(product); + assertEquals("BarCode", product.getLabel()); } @Test - public void whenProductTypeBook_ThenLabelIsbn(){ - Product product=new Product("AutoBiography","Book"); - product=productService.applyLabelToProduct(product); - assertEquals("ISBN",product.getLabel()); + public void whenProductTypeBook_ThenLabelIsbn() { + Product product = new Product("AutoBiography", "Book"); + product = productService.applyLabelToProduct(product); + assertEquals("ISBN", product.getLabel()); } } diff --git a/guest/webservices/rest-client/WebContent/META-INF/MANIFEST.MF b/guest/webservices/rest-client/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/guest/webservices/rest-client/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/guest/webservices/rest-client/pom.xml b/guest/webservices/rest-client/pom.xml new file mode 100644 index 0000000000..af03ac1948 --- /dev/null +++ b/guest/webservices/rest-client/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + com.stackify + rest-client + 0.0.1-SNAPSHOT + war + + + + maven-compiler-plugin + 3.5 + + 1.8 + 1.8 + + + + maven-war-plugin + 2.6 + + WebContent + false + + + + + \ No newline at end of file diff --git a/guest/webservices/rest-client/rest-client/.angular-cli.json b/guest/webservices/rest-client/rest-client/.angular-cli.json new file mode 100644 index 0000000000..5d1839d374 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/.angular-cli.json @@ -0,0 +1,57 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "rest-client" + }, + "apps": [ + { + "root": "src", + "outDir": "dist", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "styles.css" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "lint": [ + { + "project": "src/tsconfig.app.json" + }, + { + "project": "src/tsconfig.spec.json" + }, + { + "project": "e2e/tsconfig.e2e.json" + } + ], + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "css", + "component": {} + } +} diff --git a/guest/webservices/rest-client/rest-client/.editorconfig b/guest/webservices/rest-client/rest-client/.editorconfig new file mode 100644 index 0000000000..6e87a003da --- /dev/null +++ b/guest/webservices/rest-client/rest-client/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/guest/webservices/rest-client/rest-client/.gitignore b/guest/webservices/rest-client/rest-client/.gitignore new file mode 100644 index 0000000000..54bfd2001e --- /dev/null +++ b/guest/webservices/rest-client/rest-client/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +testem.log +/typings + +# e2e +/e2e/*.js +/e2e/*.map + +# System Files +.DS_Store +Thumbs.db diff --git a/guest/webservices/rest-client/rest-client/README.md b/guest/webservices/rest-client/rest-client/README.md new file mode 100644 index 0000000000..b33d171f3c --- /dev/null +++ b/guest/webservices/rest-client/rest-client/README.md @@ -0,0 +1,28 @@ +# RestClient + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.1.3. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). +Before running the tests make sure you are serving the app via `ng serve`. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/guest/webservices/rest-client/rest-client/e2e/app.e2e-spec.ts b/guest/webservices/rest-client/rest-client/e2e/app.e2e-spec.ts new file mode 100644 index 0000000000..2eb6dade08 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/e2e/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { RestClientPage } from './app.po'; + +describe('rest-client App', () => { + let page: RestClientPage; + + beforeEach(() => { + page = new RestClientPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('Welcome to app!!'); + }); +}); diff --git a/guest/webservices/rest-client/rest-client/e2e/app.po.ts b/guest/webservices/rest-client/rest-client/e2e/app.po.ts new file mode 100644 index 0000000000..1e111a7ff6 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/e2e/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class RestClientPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/guest/webservices/rest-client/rest-client/e2e/tsconfig.e2e.json b/guest/webservices/rest-client/rest-client/e2e/tsconfig.e2e.json new file mode 100644 index 0000000000..e2a9a2fc77 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/e2e/tsconfig.e2e.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/e2e", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "node" + ] + } +} diff --git a/guest/webservices/rest-client/rest-client/karma.conf.js b/guest/webservices/rest-client/rest-client/karma.conf.js new file mode 100644 index 0000000000..4d9ab9d948 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/karma.conf.js @@ -0,0 +1,33 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/0.13/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular/cli'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular/cli/plugins/karma') + ], + client:{ + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + reports: [ 'html', 'lcovonly' ], + fixWebpackSourcePaths: true + }, + angularCli: { + environment: 'dev' + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; diff --git a/guest/webservices/rest-client/rest-client/package.json b/guest/webservices/rest-client/rest-client/package.json new file mode 100644 index 0000000000..b10090830c --- /dev/null +++ b/guest/webservices/rest-client/rest-client/package.json @@ -0,0 +1,48 @@ +{ + "name": "rest-client", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^4.0.0", + "@angular/common": "^4.0.0", + "@angular/compiler": "^4.0.0", + "@angular/core": "^4.0.0", + "@angular/forms": "^4.0.0", + "@angular/http": "^4.0.0", + "@angular/platform-browser": "^4.0.0", + "@angular/platform-browser-dynamic": "^4.0.0", + "@angular/router": "^4.0.0", + "core-js": "^2.4.1", + "rxjs": "^5.1.0", + "zone.js": "^0.8.4" + }, + "devDependencies": { + "@angular/cli": "1.1.3", + "@angular/compiler-cli": "^4.0.0", + "@angular/language-service": "^4.0.0", + "@types/jasmine": "2.5.45", + "@types/node": "~6.0.60", + "codelyzer": "~3.0.1", + "jasmine-core": "~2.6.2", + "jasmine-spec-reporter": "~4.1.0", + "karma": "~1.7.0", + "karma-chrome-launcher": "~2.1.1", + "karma-cli": "~1.0.1", + "karma-coverage-istanbul-reporter": "^1.2.1", + "karma-jasmine": "~1.1.0", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~5.1.2", + "ts-node": "~3.0.4", + "tslint": "~5.3.2", + "typescript": "~2.3.3" + } +} diff --git a/guest/webservices/rest-client/rest-client/protractor.conf.js b/guest/webservices/rest-client/rest-client/protractor.conf.js new file mode 100644 index 0000000000..7ee3b5ee86 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './e2e/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: 'e2e/tsconfig.e2e.json' + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; diff --git a/guest/webservices/rest-client/rest-client/src/app/app.component.css b/guest/webservices/rest-client/rest-client/src/app/app.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/guest/webservices/rest-client/rest-client/src/app/app.component.html b/guest/webservices/rest-client/rest-client/src/app/app.component.html new file mode 100644 index 0000000000..94dc25088b --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/app.component.html @@ -0,0 +1,13 @@ + + + + Angular QuickStart + + + + + + + loading users component + + \ No newline at end of file diff --git a/guest/webservices/rest-client/rest-client/src/app/app.component.spec.ts b/guest/webservices/rest-client/rest-client/src/app/app.component.spec.ts new file mode 100644 index 0000000000..7d2799ceb6 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/app.component.spec.ts @@ -0,0 +1,32 @@ +import { TestBed, async } from '@angular/core/testing'; + +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + }).compileComponents(); + })); + + it('should create the app', async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); + + it(`should have as title 'app'`, async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('app'); + })); + + it('should render title in a h1 tag', async(() => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!'); + })); +}); diff --git a/guest/webservices/rest-client/rest-client/src/app/app.component.ts b/guest/webservices/rest-client/rest-client/src/app/app.component.ts new file mode 100644 index 0000000000..7b0f672831 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'] +}) +export class AppComponent { + title = 'app'; +} diff --git a/guest/webservices/rest-client/rest-client/src/app/app.module.ts b/guest/webservices/rest-client/rest-client/src/app/app.module.ts new file mode 100644 index 0000000000..fe90536b1e --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/app.module.ts @@ -0,0 +1,25 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { HttpModule } from '@angular/http'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { UsersComponent } from './users.component'; +import { RouterModule } from '@angular/router'; + +@NgModule({ + declarations: [ + AppComponent, + UsersComponent + ], + imports: [ + BrowserModule, + HttpModule, + FormsModule, + RouterModule.forRoot([ + { path: '', component: AppComponent }, + { path: 'users', component: UsersComponent }])], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/guest/webservices/rest-client/rest-client/src/app/app.service.ts b/guest/webservices/rest-client/rest-client/src/app/app.service.ts new file mode 100644 index 0000000000..cf57aecbc9 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/app.service.ts @@ -0,0 +1,36 @@ +import {Injectable} from '@angular/core'; +import { Http, Response, Headers, RequestOptions } from '@angular/http'; +import 'rxjs/add/operator/map'; + +export class User { + constructor( + public email: string, + public name: string) { } +} + +@Injectable() +export class UserService { + constructor( + private _http: Http){} + + url = 'http://localhost:8080/rest-server/users'; + + addUser(user){ + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({ headers: headers}); + + return this._http.post(this.url, JSON.stringify(user), options) + .map( + (_response: Response) => { + return _response; + }, + err => alert('Error adding user')); + } + + getUsers() { + return this._http.get(this.url) + .map((_response: Response) => { + return _response.json(); + }); + } +} \ No newline at end of file diff --git a/guest/webservices/rest-client/rest-client/src/app/users.component.html b/guest/webservices/rest-client/rest-client/src/app/users.component.html new file mode 100644 index 0000000000..bbf9289080 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/users.component.html @@ -0,0 +1,15 @@ +
+Email:
+Name:
+ +
+ +
+ + + + + +
{{user.email}} +{{user.name}}
+ diff --git a/guest/webservices/rest-client/rest-client/src/app/users.component.ts b/guest/webservices/rest-client/rest-client/src/app/users.component.ts new file mode 100644 index 0000000000..6c5a383848 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/app/users.component.ts @@ -0,0 +1,39 @@ +import { Component } from '@angular/core'; +import {UserService, User} from './app.service'; + +@Component({ + selector: 'users-page', + providers: [UserService], + templateUrl: './users.component.html', + styleUrls: ['./app.component.css'] +}) +export class UsersComponent { + title = 'Users'; + + constructor( + private _service:UserService){} + + public user = {email: "", name: ""}; + public res=[]; + + addUser() { + this._service.addUser(this.user) + .subscribe( () => this.getUsers()); + } + + getUsers() { + this._service.getUsers() + .subscribe( + users => { + this.res=[]; + users.forEach(usr => { + this.res.push( + new User( + usr.email, + usr.name + ) + ) + }); + }); + } +} diff --git a/guest/webservices/rest-client/rest-client/src/assets/.gitkeep b/guest/webservices/rest-client/rest-client/src/assets/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/guest/webservices/rest-client/rest-client/src/environments/environment.prod.ts b/guest/webservices/rest-client/rest-client/src/environments/environment.prod.ts new file mode 100644 index 0000000000..3612073bc3 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/guest/webservices/rest-client/rest-client/src/environments/environment.ts b/guest/webservices/rest-client/rest-client/src/environments/environment.ts new file mode 100644 index 0000000000..b7f639aeca --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/environments/environment.ts @@ -0,0 +1,8 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const environment = { + production: false +}; diff --git a/guest/webservices/rest-client/rest-client/src/favicon.ico b/guest/webservices/rest-client/rest-client/src/favicon.ico new file mode 100644 index 0000000000..8081c7ceaf Binary files /dev/null and b/guest/webservices/rest-client/rest-client/src/favicon.ico differ diff --git a/guest/webservices/rest-client/rest-client/src/index.html b/guest/webservices/rest-client/rest-client/src/index.html new file mode 100644 index 0000000000..5714e185ca --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/index.html @@ -0,0 +1,14 @@ + + + + + RestClient + + + + + + + + + diff --git a/guest/webservices/rest-client/rest-client/src/main.ts b/guest/webservices/rest-client/rest-client/src/main.ts new file mode 100644 index 0000000000..a9ca1caf8c --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/main.ts @@ -0,0 +1,11 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/guest/webservices/rest-client/rest-client/src/polyfills.ts b/guest/webservices/rest-client/rest-client/src/polyfills.ts new file mode 100644 index 0000000000..fd01cc9f1d --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/polyfills.ts @@ -0,0 +1,73 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following to support `@angular/animation`. */ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + +/** Evergreen browsers require these. **/ +import 'core-js/es6/reflect'; +import 'core-js/es7/reflect'; + + +/** ALL Firefox browsers require the following to support `@angular/animation`. **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +// import 'intl/locale-data/jsonp/en'; diff --git a/guest/webservices/rest-client/rest-client/src/styles.css b/guest/webservices/rest-client/rest-client/src/styles.css new file mode 100644 index 0000000000..90d4ee0072 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/guest/webservices/rest-client/rest-client/src/test.ts b/guest/webservices/rest-client/rest-client/src/test.ts new file mode 100644 index 0000000000..cd612eeb0e --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/test.ts @@ -0,0 +1,32 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare const __karma__: any; +declare const require: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function () {}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/guest/webservices/rest-client/rest-client/src/tsconfig.app.json b/guest/webservices/rest-client/rest-client/src/tsconfig.app.json new file mode 100644 index 0000000000..5e2507db58 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "es2015", + "baseUrl": "", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} diff --git a/guest/webservices/rest-client/rest-client/src/tsconfig.spec.json b/guest/webservices/rest-client/rest-client/src/tsconfig.spec.json new file mode 100644 index 0000000000..510e3f1fda --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "module": "commonjs", + "target": "es5", + "baseUrl": "", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/guest/webservices/rest-client/rest-client/src/typings.d.ts b/guest/webservices/rest-client/rest-client/src/typings.d.ts new file mode 100644 index 0000000000..ef5c7bd620 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/src/typings.d.ts @@ -0,0 +1,5 @@ +/* SystemJS module definition */ +declare var module: NodeModule; +interface NodeModule { + id: string; +} diff --git a/guest/webservices/rest-client/rest-client/tsconfig.json b/guest/webservices/rest-client/rest-client/tsconfig.json new file mode 100644 index 0000000000..a35a8ee3a4 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "baseUrl": "src", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2016", + "dom" + ] + } +} diff --git a/guest/webservices/rest-client/rest-client/tslint.json b/guest/webservices/rest-client/rest-client/tslint.json new file mode 100644 index 0000000000..dd117b3871 --- /dev/null +++ b/guest/webservices/rest-client/rest-client/tslint.json @@ -0,0 +1,135 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + "static-before-instance", + "variables-before-functions" + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "typeof-compare": true, + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ], + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true, + "no-access-missing-member": true, + "templates-use-public": true, + "invoke-injectable": true + } +} diff --git a/guest/webservices/rest-server/WebContent/META-INF/MANIFEST.MF b/guest/webservices/rest-server/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/guest/webservices/rest-server/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/guest/webservices/rest-server/WebContent/WEB-INF/web.xml b/guest/webservices/rest-server/WebContent/WEB-INF/web.xml new file mode 100644 index 0000000000..46b173c59a --- /dev/null +++ b/guest/webservices/rest-server/WebContent/WEB-INF/web.xml @@ -0,0 +1,20 @@ + + + rest-server + + rest-server + org.glassfish.jersey.servlet.ServletContainer + + javax.ws.rs.Application + com.stackify.ApplicationInitializer + + 1 + + + rest-server + /* + + \ No newline at end of file diff --git a/guest/webservices/rest-server/pom.xml b/guest/webservices/rest-server/pom.xml new file mode 100644 index 0000000000..350e7eb9c9 --- /dev/null +++ b/guest/webservices/rest-server/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + com.stackify + rest-server + 0.0.1-SNAPSHOT + war + + + + org.glassfish.jersey.containers + jersey-container-servlet + 2.25.1 + + + org.glassfish.jersey.media + jersey-media-moxy + 2.25.1 + + + io.rest-assured + rest-assured + 3.0.3 + + + junit + junit + 4.12 + + + + + + + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + maven-war-plugin + 3.0.0 + + WebContent + + + + + \ No newline at end of file diff --git a/guest/webservices/rest-server/src/main/java/com/stackify/ApplicationInitializer.java b/guest/webservices/rest-server/src/main/java/com/stackify/ApplicationInitializer.java new file mode 100644 index 0000000000..6d864e859e --- /dev/null +++ b/guest/webservices/rest-server/src/main/java/com/stackify/ApplicationInitializer.java @@ -0,0 +1,9 @@ +package com.stackify; + +import org.glassfish.jersey.server.ResourceConfig; + +public class ApplicationInitializer extends ResourceConfig { + public ApplicationInitializer() { + packages("com.stackify.services"); + } +} diff --git a/guest/webservices/rest-server/src/main/java/com/stackify/models/User.java b/guest/webservices/rest-server/src/main/java/com/stackify/models/User.java new file mode 100644 index 0000000000..8c8073357d --- /dev/null +++ b/guest/webservices/rest-server/src/main/java/com/stackify/models/User.java @@ -0,0 +1,43 @@ +package com.stackify.models; + +import javax.ws.rs.core.Link; + +public class User { + private String email; + private String name; + private Link link; + + public User() { + } + + public User(String email, String name) { + super(); + this.email = email; + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } + +} diff --git a/guest/webservices/rest-server/src/main/java/com/stackify/services/CorsFilter.java b/guest/webservices/rest-server/src/main/java/com/stackify/services/CorsFilter.java new file mode 100644 index 0000000000..267aa6fd61 --- /dev/null +++ b/guest/webservices/rest-server/src/main/java/com/stackify/services/CorsFilter.java @@ -0,0 +1,19 @@ +package com.stackify.services; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.ext.Provider; + +@Provider +public class CorsFilter implements ContainerResponseFilter { + + @Override + public void filter(final ContainerRequestContext requestContext, + final ContainerResponseContext response) throws IOException { + response.getHeaders().add("Access-Control-Allow-Origin", "*"); + response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept"); + } +} diff --git a/guest/webservices/rest-server/src/main/java/com/stackify/services/UserService.java b/guest/webservices/rest-server/src/main/java/com/stackify/services/UserService.java new file mode 100644 index 0000000000..e78ed4627a --- /dev/null +++ b/guest/webservices/rest-server/src/main/java/com/stackify/services/UserService.java @@ -0,0 +1,33 @@ +package com.stackify.services; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.stackify.models.User; + +@Path("/users") +public class UserService { + private static List users = new ArrayList<>(); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response addUser(User user) { + users.add(user); + return Response.ok() + .build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getUsers() { + return users; + } +} diff --git a/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java b/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java new file mode 100644 index 0000000000..064951fbbe --- /dev/null +++ b/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java @@ -0,0 +1,34 @@ +package com.stackify.services; + +import org.junit.Test; + +import io.restassured.RestAssured; +import static io.restassured.RestAssured.*; +import static org.hamcrest.CoreMatchers.*; + +public class UserServiceTest { + @Test + public void whenAddUser_thenGetUserOk() { + RestAssured.baseURI = "http://localhost:8080/rest-server"; + + //@formatter:off + + String json = "{\"email\":\"john@gmail.com\",\"name\":\"John\"}"; + given() + .contentType("application/json") + .body(json) + .when() + .post("/users") + .then() + .statusCode(200); + + when() + .get("/users") + .then() + .contentType("application/json") + .body("name", hasItem("John")) + .body("email", hasItem("john@gmail.com")); + + //@formatter:on + } +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/JAXWSClient.java b/guest/webservices/soap_client/src/main/java/com/stackify/JAXWSClient.java new file mode 100644 index 0000000000..5542fbde20 --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/JAXWSClient.java @@ -0,0 +1,19 @@ +package com.stackify; + +import com.stackify.services.DefaultUserImplService; +import com.stackify.services.User; +import com.stackify.services.UserService; +import com.stackify.services.Users; + +public class JAXWSClient { + public static void main(String[] args) { + DefaultUserImplService service = new DefaultUserImplService(); + User user = new User(); + user.setEmail("john@gmail.com"); + user.setName("John"); + UserService port = service.getDefaultUserImplPort(); + port.addUser(user); + Users users = port.getUsers(); + System.out.println(users.getUsers().iterator().next().getName()); + } +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/services/DefaultUserImplService.java b/guest/webservices/soap_client/src/main/java/com/stackify/services/DefaultUserImplService.java new file mode 100644 index 0000000000..821b969166 --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/services/DefaultUserImplService.java @@ -0,0 +1,94 @@ + +package com.stackify.services; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceFeature; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.9-b130926.1035 + * Generated source version: 2.2 + * + */ +@WebServiceClient(name = "DefaultUserImplService", targetNamespace = "http://services.stackify.com/", wsdlLocation = "http://localhost:8080/users?wsdl") +public class DefaultUserImplService + extends Service +{ + + private final static URL DEFAULTUSERIMPLSERVICE_WSDL_LOCATION; + private final static WebServiceException DEFAULTUSERIMPLSERVICE_EXCEPTION; + private final static QName DEFAULTUSERIMPLSERVICE_QNAME = new QName("http://services.stackify.com/", "DefaultUserImplService"); + + static { + URL url = null; + WebServiceException e = null; + try { + url = new URL("http://localhost:8080/users?wsdl"); + } catch (MalformedURLException ex) { + e = new WebServiceException(ex); + } + DEFAULTUSERIMPLSERVICE_WSDL_LOCATION = url; + DEFAULTUSERIMPLSERVICE_EXCEPTION = e; + } + + public DefaultUserImplService() { + super(__getWsdlLocation(), DEFAULTUSERIMPLSERVICE_QNAME); + } + + public DefaultUserImplService(WebServiceFeature... features) { + super(__getWsdlLocation(), DEFAULTUSERIMPLSERVICE_QNAME, features); + } + + public DefaultUserImplService(URL wsdlLocation) { + super(wsdlLocation, DEFAULTUSERIMPLSERVICE_QNAME); + } + + public DefaultUserImplService(URL wsdlLocation, WebServiceFeature... features) { + super(wsdlLocation, DEFAULTUSERIMPLSERVICE_QNAME, features); + } + + public DefaultUserImplService(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public DefaultUserImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { + super(wsdlLocation, serviceName, features); + } + + /** + * + * @return + * returns UserService + */ + @WebEndpoint(name = "DefaultUserImplPort") + public UserService getDefaultUserImplPort() { + return super.getPort(new QName("http://services.stackify.com/", "DefaultUserImplPort"), UserService.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns UserService + */ + @WebEndpoint(name = "DefaultUserImplPort") + public UserService getDefaultUserImplPort(WebServiceFeature... features) { + return super.getPort(new QName("http://services.stackify.com/", "DefaultUserImplPort"), UserService.class, features); + } + + private static URL __getWsdlLocation() { + if (DEFAULTUSERIMPLSERVICE_EXCEPTION!= null) { + throw DEFAULTUSERIMPLSERVICE_EXCEPTION; + } + return DEFAULTUSERIMPLSERVICE_WSDL_LOCATION; + } + +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/services/ObjectFactory.java b/guest/webservices/soap_client/src/main/java/com/stackify/services/ObjectFactory.java new file mode 100644 index 0000000000..d992521d9f --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/services/ObjectFactory.java @@ -0,0 +1,48 @@ + +package com.stackify.services; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.stackify.services package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.stackify.services + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link User } + * + */ + public User createUser() { + return new User(); + } + + /** + * Create an instance of {@link Users } + * + */ + public Users createUsers() { + return new Users(); + } + +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/services/User.java b/guest/webservices/soap_client/src/main/java/com/stackify/services/User.java new file mode 100644 index 0000000000..d9d517f83d --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/services/User.java @@ -0,0 +1,87 @@ + +package com.stackify.services; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for user complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="user">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "user", propOrder = { + "email", + "name" +}) +public class User { + + protected String email; + protected String name; + + /** + * Gets the value of the email property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEmail() { + return email; + } + + /** + * Sets the value of the email property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEmail(String value) { + this.email = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/services/UserService.java b/guest/webservices/soap_client/src/main/java/com/stackify/services/UserService.java new file mode 100644 index 0000000000..87ab1f2f75 --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/services/UserService.java @@ -0,0 +1,47 @@ + +package com.stackify.services; + +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebResult; +import javax.jws.WebService; +import javax.jws.soap.SOAPBinding; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.ws.Action; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.9-b130926.1035 + * Generated source version: 2.2 + * + */ +@WebService(name = "UserService", targetNamespace = "http://services.stackify.com/") +@SOAPBinding(style = SOAPBinding.Style.RPC) +@XmlSeeAlso({ + ObjectFactory.class +}) +public interface UserService { + + + /** + * + * @param arg0 + */ + @WebMethod + @Action(input = "http://services.stackify.com/UserService/addUserRequest", output = "http://services.stackify.com/UserService/addUserResponse") + public void addUser( + @WebParam(name = "arg0", partName = "arg0") + User arg0); + + /** + * + * @return + * returns com.stackify.services.Users + */ + @WebMethod + @WebResult(partName = "return") + @Action(input = "http://services.stackify.com/UserService/getUsersRequest", output = "http://services.stackify.com/UserService/getUsersResponse") + public Users getUsers(); + +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/services/Users.java b/guest/webservices/soap_client/src/main/java/com/stackify/services/Users.java new file mode 100644 index 0000000000..bde0e47b11 --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/services/Users.java @@ -0,0 +1,69 @@ + +package com.stackify.services; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for users complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="users">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="users" type="{http://services.stackify.com/}user" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "users", propOrder = { + "users" +}) +public class Users { + + @XmlElement(nillable = true) + protected List users; + + /** + * Gets the value of the users property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the users property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getUsers().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link User } + * + * + */ + public List getUsers() { + if (users == null) { + users = new ArrayList(); + } + return this.users; + } + +} diff --git a/guest/webservices/soap_client/src/main/java/com/stackify/services/package-info.java b/guest/webservices/soap_client/src/main/java/com/stackify/services/package-info.java new file mode 100644 index 0000000000..af6d2bc25e --- /dev/null +++ b/guest/webservices/soap_client/src/main/java/com/stackify/services/package-info.java @@ -0,0 +1,2 @@ +@javax.xml.bind.annotation.XmlSchema(namespace = "http://services.stackify.com/") +package com.stackify.services; diff --git a/guest/webservices/soap_example/src/main/java/com/stackify/ServicePublisher.java b/guest/webservices/soap_example/src/main/java/com/stackify/ServicePublisher.java new file mode 100644 index 0000000000..3a10b6e285 --- /dev/null +++ b/guest/webservices/soap_example/src/main/java/com/stackify/ServicePublisher.java @@ -0,0 +1,11 @@ +package com.stackify; + +import javax.xml.ws.Endpoint; + +import com.stackify.services.DefaultUserImpl; + +public class ServicePublisher { + public static void main(String[] args) { + Endpoint.publish("http://localhost:8080/users", new DefaultUserImpl()); + } +} diff --git a/guest/webservices/soap_example/src/main/java/com/stackify/models/User.java b/guest/webservices/soap_example/src/main/java/com/stackify/models/User.java new file mode 100644 index 0000000000..1a9741154d --- /dev/null +++ b/guest/webservices/soap_example/src/main/java/com/stackify/models/User.java @@ -0,0 +1,32 @@ +package com.stackify.models; + +public class User { + private String email; + private String name; + + public User() { + } + + public User(String email, String name) { + super(); + this.email = email; + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/guest/webservices/soap_example/src/main/java/com/stackify/models/Users.java b/guest/webservices/soap_example/src/main/java/com/stackify/models/Users.java new file mode 100644 index 0000000000..2323a74614 --- /dev/null +++ b/guest/webservices/soap_example/src/main/java/com/stackify/models/Users.java @@ -0,0 +1,16 @@ +package com.stackify.models; + +import java.util.List; + +public class Users { + List users; + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + +} diff --git a/guest/webservices/soap_example/src/main/java/com/stackify/services/DefaultUserImpl.java b/guest/webservices/soap_example/src/main/java/com/stackify/services/DefaultUserImpl.java new file mode 100644 index 0000000000..87d7d646c1 --- /dev/null +++ b/guest/webservices/soap_example/src/main/java/com/stackify/services/DefaultUserImpl.java @@ -0,0 +1,27 @@ +package com.stackify.services; + +import java.util.ArrayList; + +import javax.jws.WebService; + +import com.stackify.models.User; +import com.stackify.models.Users; + +@WebService(endpointInterface = "com.stackify.services.UserService") +public class DefaultUserImpl implements UserService { + + ArrayList usersList = new ArrayList<>(); + + @Override + public void addUser(User user) { + usersList.add(user); + } + + @Override + public Users getUsers() { + Users users = new Users(); + users.setUsers(usersList); + return users; + } + +} diff --git a/guest/webservices/soap_example/src/main/java/com/stackify/services/UserService.java b/guest/webservices/soap_example/src/main/java/com/stackify/services/UserService.java new file mode 100644 index 0000000000..8c57fbd061 --- /dev/null +++ b/guest/webservices/soap_example/src/main/java/com/stackify/services/UserService.java @@ -0,0 +1,19 @@ +package com.stackify.services; + +import javax.jws.WebMethod; +import javax.jws.WebService; +import javax.jws.soap.SOAPBinding; + +import com.stackify.models.User; +import com.stackify.models.Users; + +@WebService +@SOAPBinding(style = SOAPBinding.Style.RPC) +public interface UserService { + + @WebMethod + public void addUser(User user); + + @WebMethod + public Users getUsers(); +} diff --git a/guest/webservices/spring-rest-service/WebContent/META-INF/MANIFEST.MF b/guest/webservices/spring-rest-service/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/guest/webservices/spring-rest-service/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/guest/webservices/spring-rest-service/pom.xml b/guest/webservices/spring-rest-service/pom.xml new file mode 100644 index 0000000000..11082cf17b --- /dev/null +++ b/guest/webservices/spring-rest-service/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + com.stackify + spring-rest-service + 0.0.1-SNAPSHOT + war + + + org.springframework.boot + spring-boot-starter-parent + 1.5.4.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-hateoas + + + io.springfox + springfox-swagger2 + 2.7.0 + + + io.springfox + springfox-swagger-ui + 2.7.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/guest/webservices/spring-rest-service/src/main/java/com/stackify/Application.java b/guest/webservices/spring-rest-service/src/main/java/com/stackify/Application.java new file mode 100644 index 0000000000..b45ed8094f --- /dev/null +++ b/guest/webservices/spring-rest-service/src/main/java/com/stackify/Application.java @@ -0,0 +1,12 @@ +package com.stackify; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/guest/webservices/spring-rest-service/src/main/java/com/stackify/config/SwaggerConfig.java b/guest/webservices/spring-rest-service/src/main/java/com/stackify/config/SwaggerConfig.java new file mode 100644 index 0000000000..0e9567b452 --- /dev/null +++ b/guest/webservices/spring-rest-service/src/main/java/com/stackify/config/SwaggerConfig.java @@ -0,0 +1,22 @@ +package com.stackify.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).select() + .apis(RequestHandlerSelectors.basePackage("com.stackify.controllers")) + .paths(PathSelectors.any()) + .build(); + } +} diff --git a/guest/webservices/spring-rest-service/src/main/java/com/stackify/controllers/UserController.java b/guest/webservices/spring-rest-service/src/main/java/com/stackify/controllers/UserController.java new file mode 100644 index 0000000000..361dbde38d --- /dev/null +++ b/guest/webservices/spring-rest-service/src/main/java/com/stackify/controllers/UserController.java @@ -0,0 +1,52 @@ +package com.stackify.controllers; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.hateoas.Link; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.stackify.models.User; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; + +@RestController +public class UserController { + + private static List users = new ArrayList<>(); + + @PostMapping(value = "/users", consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + public void addUser(@RequestBody User user) { + users.add(user); + } + + @GetMapping("/users") + public List getUsers() { + users.forEach(user -> { + Link selfLink = linkTo(methodOn(UserController.class).getUsers()).slash(user.getEmail()) + .withSelfRel(); + user.getLinks().clear(); + user.add(selfLink); + }); + return users; + } + + @GetMapping("/users/{email}") + public User getUser(@PathVariable String email) { + User us = users.stream() + .filter(user -> !user.getEmail() + .equals(email)) + .findAny() + .orElse(null); + return us; + } + +} diff --git a/guest/webservices/spring-rest-service/src/main/java/com/stackify/models/User.java b/guest/webservices/spring-rest-service/src/main/java/com/stackify/models/User.java new file mode 100644 index 0000000000..b52e7f0f87 --- /dev/null +++ b/guest/webservices/spring-rest-service/src/main/java/com/stackify/models/User.java @@ -0,0 +1,34 @@ +package com.stackify.models; + +import org.springframework.hateoas.ResourceSupport; + +public class User extends ResourceSupport { + private String email; + private String name; + + public User() { + } + + public User(String email, String name) { + super(); + this.email = email; + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/jmh/pom.xml b/jmh/pom.xml new file mode 100644 index 0000000000..8ecfaa9651 --- /dev/null +++ b/jmh/pom.xml @@ -0,0 +1,52 @@ + + 4.0.0 + com.baeldung + jmh + jar + 1.0-SNAPSHOT + jmh + http://maven.apache.org + + + UTF-8 + UTF-8 + 1.8 + + + + + org.openjdk.jmh + jmh-core + 1.19 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + junit + junit + 3.8.1 + test + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.baeldung.Application + + + + + + + + \ No newline at end of file diff --git a/jmh/src/main/java/com/baeldung/Application.java b/jmh/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..28e70740e0 --- /dev/null +++ b/jmh/src/main/java/com/baeldung/Application.java @@ -0,0 +1,14 @@ +package com.baeldung; + +import java.io.IOException; + +import org.openjdk.jmh.Main; +import org.openjdk.jmh.runner.RunnerException; + +public class Application { + + public static void main(String[] args) throws RunnerException, IOException { + Main.main(args); + } + +} diff --git a/jmh/src/main/java/com/baeldung/BenchMark.java b/jmh/src/main/java/com/baeldung/BenchMark.java new file mode 100644 index 0000000000..f2b984d211 --- /dev/null +++ b/jmh/src/main/java/com/baeldung/BenchMark.java @@ -0,0 +1,12 @@ +package com.baeldung; + +import org.openjdk.jmh.annotations.Benchmark; + +public class BenchMark { + + @Benchmark + public void init() { + + } + +} diff --git a/jmh/src/main/resources/META-INF/BenchmarkList b/jmh/src/main/resources/META-INF/BenchmarkList new file mode 100644 index 0000000000..e69de29bb2 diff --git a/jmh/src/test/java/com/baeldung/AppTest.java b/jmh/src/test/java/com/baeldung/AppTest.java new file mode 100644 index 0000000000..c9f61455bd --- /dev/null +++ b/jmh/src/test/java/com/baeldung/AppTest.java @@ -0,0 +1,38 @@ +package com.baeldung; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/kotlin-mockito/README.md b/kotlin-mockito/README.md new file mode 100644 index 0000000000..1408bc1ebd --- /dev/null +++ b/kotlin-mockito/README.md @@ -0,0 +1,8 @@ +## Relevant articles: + +- [Introduction to the Kotlin Language](http://www.baeldung.com/kotlin) +- [A guide to the “when{}” block in Kotlin](http://www.baeldung.com/kotlin-when) +- [Comprehensive Guide to Null Safety in Kotlin](http://www.baeldung.com/kotlin-null-safety) +- [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) +- [Difference Between “==” and “===” in Kotlin](http://www.baeldung.com/kotlin-equality-operators) +- [Generics in Kotlin](http://www.baeldung.com/kotlin-generics) diff --git a/kotlin-mockito/pom.xml b/kotlin-mockito/pom.xml new file mode 100644 index 0000000000..abb43f4109 --- /dev/null +++ b/kotlin-mockito/pom.xml @@ -0,0 +1,121 @@ + + + 4.0.0 + + kotlin-mockito + 1.0-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + org.mockito + mockito-core + ${mockito.version} + test + + + junit + junit + ${junit.version} + test + + + com.nhaarman + mockito-kotlin + ${mockito-kotlin.version} + test + + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + compile + + compile + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + + + + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler.version} + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + + + + 2.8.9 + 4.12 + 1.1.2-4 + 1.5.0 + 3.5.1 + + + diff --git a/kotlin-mockito/src/main/java/com/baeldung/java/ArrayExample.java b/kotlin-mockito/src/main/java/com/baeldung/java/ArrayExample.java new file mode 100644 index 0000000000..ef91db517b --- /dev/null +++ b/kotlin-mockito/src/main/java/com/baeldung/java/ArrayExample.java @@ -0,0 +1,24 @@ +package com.baeldung.java; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class ArrayExample { + + public int sumValues(int[] nums) { + int res = 0; + + for (int x:nums) { + res += x; + } + + return res; + } + + public void writeList() throws IOException { + File file = new File("E://file.txt"); + FileReader fr = new FileReader(file); + fr.close(); + } +} diff --git a/kotlin-mockito/src/main/java/com/baeldung/java/Customer.java b/kotlin-mockito/src/main/java/com/baeldung/java/Customer.java new file mode 100644 index 0000000000..0156bf7b44 --- /dev/null +++ b/kotlin-mockito/src/main/java/com/baeldung/java/Customer.java @@ -0,0 +1,24 @@ +package com.baeldung.java; + +public class Customer { + + private String firstName; + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + +} diff --git a/kotlin-mockito/src/main/java/com/baeldung/java/StringUtils.java b/kotlin-mockito/src/main/java/com/baeldung/java/StringUtils.java new file mode 100644 index 0000000000..f405924cdf --- /dev/null +++ b/kotlin-mockito/src/main/java/com/baeldung/java/StringUtils.java @@ -0,0 +1,7 @@ +package com.baeldung.java; + +public class StringUtils { + public static String toUpperCase(String name) { + return name.toUpperCase(); + } +} diff --git a/kotlin-mockito/src/main/kotlin/com/baeldung/kotlin/BookService.kt b/kotlin-mockito/src/main/kotlin/com/baeldung/kotlin/BookService.kt new file mode 100644 index 0000000000..993ee555af --- /dev/null +++ b/kotlin-mockito/src/main/kotlin/com/baeldung/kotlin/BookService.kt @@ -0,0 +1,6 @@ +package com.baeldung.kotlin + +interface BookService { + fun inStock(bookId: Int): Boolean + fun lend(bookId: Int, memberId: Int) +} \ No newline at end of file diff --git a/kotlin-mockito/src/main/kotlin/com/baeldung/kotlin/LendBookManager.kt b/kotlin-mockito/src/main/kotlin/com/baeldung/kotlin/LendBookManager.kt new file mode 100644 index 0000000000..5a4718162a --- /dev/null +++ b/kotlin-mockito/src/main/kotlin/com/baeldung/kotlin/LendBookManager.kt @@ -0,0 +1,11 @@ +package com.baeldung.kotlin + +class LendBookManager(val bookService:BookService) { + fun checkout(bookId: Int, memberId: Int) { + if(bookService.inStock(bookId)) { + bookService.lend(bookId, memberId) + } else { + throw IllegalStateException("Book is not available") + } + } +} diff --git a/kotlin-mockito/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java b/kotlin-mockito/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java new file mode 100644 index 0000000000..370f24785a --- /dev/null +++ b/kotlin-mockito/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.kotlin; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JavaCallToKotlinUnitTest { + @Test + public void givenKotlinClass_whenCallFromJava_shouldProduceResults() { + //when + int res = new MathematicsOperations().addTwoNumbers(2, 4); + + //then + assertEquals(6, res); + + } +} diff --git a/kotlin-mockito/src/test/kotlin/com/baeldung/kotlin/LendBookManagerTest.kt b/kotlin-mockito/src/test/kotlin/com/baeldung/kotlin/LendBookManagerTest.kt new file mode 100644 index 0000000000..ab08273686 --- /dev/null +++ b/kotlin-mockito/src/test/kotlin/com/baeldung/kotlin/LendBookManagerTest.kt @@ -0,0 +1,30 @@ +package com.baeldung.kotlin; + +import org.junit.Test +import org.mockito.Mockito + +class LibraryManagementTest { + @Test(expected = IllegalStateException::class) + fun whenBookIsNotAvailable_thenAnExceptionIsThrown() { + val mockBookService = Mockito.mock(BookService::class.java) + + Mockito.`when`(mockBookService.inStock(100)).thenReturn(false) + + val manager = LendBookManager(mockBookService) + + manager.checkout(100, 1) + } + + @Test + fun whenBookIsAvailable_thenLendMethodIsCalled() { + val mockBookService = Mockito.mock(BookService::class.java) + + Mockito.`when`(mockBookService.inStock(100)).thenReturn(true) + + val manager = LendBookManager(mockBookService) + + manager.checkout(100, 1) + + Mockito.verify(mockBookService).lend(100, 1) + } +} \ No newline at end of file diff --git a/kotlin-mockito/src/test/kotlin/com/baeldung/kotlin/LendBookManagerTestMockitoKotlin.kt b/kotlin-mockito/src/test/kotlin/com/baeldung/kotlin/LendBookManagerTestMockitoKotlin.kt new file mode 100644 index 0000000000..1ff4e20c61 --- /dev/null +++ b/kotlin-mockito/src/test/kotlin/com/baeldung/kotlin/LendBookManagerTestMockitoKotlin.kt @@ -0,0 +1,32 @@ +package com.baeldung.kotlin; + +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import com.nhaarman.mockito_kotlin.whenever +import org.junit.Test + +class LibraryManagementTestMockitoKotlin { + @Test(expected = IllegalStateException::class) + fun whenBookIsNotAvailable_thenAnExceptionIsThrown() { + val mockBookService = mock() + + whenever(mockBookService.inStock(100)).thenReturn(false) + + val manager = LendBookManager(mockBookService) + + manager.checkout(100, 1) + } + + @Test + fun whenBookIsAvailable_thenLendMethodIsCalled() { + val mockBookService : BookService = mock() + + whenever(mockBookService.inStock(100)).thenReturn(true) + + val manager = LendBookManager(mockBookService) + + manager.checkout(100, 1) + + verify(mockBookService).lend(100, 1) + } +} \ No newline at end of file diff --git a/libraries/README.md b/libraries/README.md index f69885a30f..81d716cf48 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -16,6 +16,7 @@ - [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm) - [Introduction to HikariCP](http://www.baeldung.com/hikaricp) - [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave) +- [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. diff --git a/libraries/pom.xml b/libraries/pom.xml index 45b371061e..406887e4b0 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -70,6 +70,32 @@ + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.5 + + + org.asciidoctor + asciidoctorj-pdf + 1.5.0-alpha.15 + + + + + output-pdf + generate-resources + + process-asciidoc + + + + + src/docs/asciidoc + target/docs/asciidoc + pdf + + @@ -80,6 +106,11 @@ cglib ${cglib.version} + + commons-beanutils + commons-beanutils + ${commons-beanutils.version} + org.apache.commons commons-lang3 @@ -356,11 +387,17 @@ ${junit.version} test + + info.debatty + java-lsh + ${java-lsh.version} + 0.7.0 3.2.4 3.5 + 1.9.3 1.9.2 1.2 3.21.0-GA @@ -383,6 +420,7 @@ 4.1.10.Final 4.1 4.12 + 0.10 - \ No newline at end of file + diff --git a/libraries/src/docs/asciidoc/test.adoc b/libraries/src/docs/asciidoc/test.adoc new file mode 100644 index 0000000000..5a86a00440 --- /dev/null +++ b/libraries/src/docs/asciidoc/test.adoc @@ -0,0 +1,3 @@ +== Introduction Section + +Hi. I'm a simple test to see if this Maven build is working. If you see me in a nice PDF, then it means everything is [red]#working#. \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/asciidoctor/AsciidoctorDemo.java b/libraries/src/main/java/com/baeldung/asciidoctor/AsciidoctorDemo.java index a986c35126..6ecf4ff964 100644 --- a/libraries/src/main/java/com/baeldung/asciidoctor/AsciidoctorDemo.java +++ b/libraries/src/main/java/com/baeldung/asciidoctor/AsciidoctorDemo.java @@ -13,21 +13,21 @@ public class AsciidoctorDemo { private final Asciidoctor asciidoctor; - public AsciidoctorDemo() { + AsciidoctorDemo() { asciidoctor = create(); } public void generatePDFFromString(final String input) { final Map options = options().inPlace(true) - .backend("pdf") - .asMap(); + .backend("pdf") + .asMap(); + final String outfile = asciidoctor.convertFile(new File("sample.adoc"), options); } - public String generateHTMLFromString(final String input) { - final String output = asciidoctor.convert("Hello _Baeldung_!", new HashMap()); - return output; + String generateHTMLFromString(final String input) { + return asciidoctor.convert("Hello _Baeldung_!", new HashMap()); } } diff --git a/libraries/src/main/java/com/baeldung/commons/beanutils/Course.java b/libraries/src/main/java/com/baeldung/commons/beanutils/Course.java new file mode 100644 index 0000000000..03251586fd --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/beanutils/Course.java @@ -0,0 +1,35 @@ +package com.baeldung.commons.beanutils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Course { + private String name; + private List codes; + private Map enrolledStudent = new HashMap(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCodes() { + return codes; + } + + public void setCodes(List codes) { + this.codes = codes; + } + + public void setEnrolledStudent(String enrolledId, Student student) { + enrolledStudent.put(enrolledId, student); + } + + public Student getEnrolledStudent(String enrolledId) { + return enrolledStudent.get(enrolledId); + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/beanutils/CourseService.java b/libraries/src/main/java/com/baeldung/commons/beanutils/CourseService.java new file mode 100644 index 0000000000..f519365dab --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/beanutils/CourseService.java @@ -0,0 +1,34 @@ +package com.baeldung.commons.beanutils; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import org.apache.commons.beanutils.PropertyUtils; + +public class CourseService { + + public static void setValues(Course course, String name, List codes) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + // Setting the simple properties + PropertyUtils.setSimpleProperty(course, "name", name); + PropertyUtils.setSimpleProperty(course, "codes", codes); + } + + public static void setIndexedValue(Course course, int codeIndex, String code) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + // Setting the indexed properties + PropertyUtils.setIndexedProperty(course, "codes[" + codeIndex + "]", code); + } + + public static void setMappedValue(Course course, String enrollId, Student student) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + // Setting the mapped properties + PropertyUtils.setMappedProperty(course, "enrolledStudent(" + enrollId + ")", student); + } + + public static String getNestedValue(Course course, String enrollId, String nestedPropertyName) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + return (String) PropertyUtils.getNestedProperty( + course, "enrolledStudent(" + enrollId + ")." + nestedPropertyName); + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/beanutils/Student.java b/libraries/src/main/java/com/baeldung/commons/beanutils/Student.java new file mode 100644 index 0000000000..3790bf6f9e --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/beanutils/Student.java @@ -0,0 +1,13 @@ +package com.baeldung.commons.beanutils; + +public class Student { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/libraries/src/main/java/com/baeldung/jmh/JmhDemo.java b/libraries/src/main/java/com/baeldung/jmh/JmhDemo.java index bcd585e586..6f1e8bc8cf 100644 --- a/libraries/src/main/java/com/baeldung/jmh/JmhDemo.java +++ b/libraries/src/main/java/com/baeldung/jmh/JmhDemo.java @@ -6,9 +6,7 @@ import org.openjdk.jmh.Main; import org.openjdk.jmh.runner.RunnerException; public class JmhDemo { - public static void main(String[] args) throws RunnerException, IOException { - Main.main(args); + Main.main(args); } - } diff --git a/libraries/src/main/java/com/baeldung/jmh/warmup/MainApplication.java b/libraries/src/main/java/com/baeldung/jmh/warmup/MainApplication.java new file mode 100644 index 0000000000..994a22c210 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jmh/warmup/MainApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.jmh.warmup; + +public class MainApplication { + + static { + long start = System.nanoTime(); + ManualClassLoader.load(); + long end = System.nanoTime(); + System.out.println("Warm Up time : " + (end - start)); + } + + public static void main(String[] args) { + long start = System.nanoTime(); + ManualClassLoader.load(); + long end = System.nanoTime(); + System.out.println("Total time taken : " + (end - start)); + } + +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/jmh/warmup/ManualClassLoader.java b/libraries/src/main/java/com/baeldung/jmh/warmup/ManualClassLoader.java new file mode 100644 index 0000000000..07cf7f6bcb --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jmh/warmup/ManualClassLoader.java @@ -0,0 +1,17 @@ +package com.baeldung.jmh.warmup; + +import com.baeldung.jmh.warmup.dummy.Dummy; + +public class ManualClassLoader { + + public static void load() { + + for (int i = 0; i < 100000; i++) { + // load all(or most) important classes + Dummy dummy = new Dummy(); + dummy.m(); + } + + } + +} diff --git a/libraries/src/main/java/com/baeldung/jmh/warmup/dummy/Dummy.java b/libraries/src/main/java/com/baeldung/jmh/warmup/dummy/Dummy.java new file mode 100644 index 0000000000..d88215548c --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jmh/warmup/dummy/Dummy.java @@ -0,0 +1,9 @@ +package com.baeldung.jmh.warmup.dummy; + +public class Dummy { + + public void m() { + + } + +} diff --git a/libraries/src/main/java/com/baeldung/quartz/JobA.java b/libraries/src/main/java/com/baeldung/quartz/JobA.java new file mode 100644 index 0000000000..76eb1118e6 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/quartz/JobA.java @@ -0,0 +1,13 @@ +package com.baeldung.quartz; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +public class JobA implements Job { + + public void execute(JobExecutionContext arg0) throws JobExecutionException { + System.out.println("This is the job A"); + } + +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/quartz/JobB.java b/libraries/src/main/java/com/baeldung/quartz/JobB.java new file mode 100644 index 0000000000..1a5e353c74 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/quartz/JobB.java @@ -0,0 +1,13 @@ +package com.baeldung.quartz; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +public class JobB implements Job { + + public void execute(JobExecutionContext arg0) throws JobExecutionException { + System.out.println("This is the job B"); + } + +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/quartz/QuartzExample.java b/libraries/src/main/java/com/baeldung/quartz/QuartzExample.java index 1e37fc028b..20853aa01b 100644 --- a/libraries/src/main/java/com/baeldung/quartz/QuartzExample.java +++ b/libraries/src/main/java/com/baeldung/quartz/QuartzExample.java @@ -21,6 +21,8 @@ public class QuartzExample { JobDetail job = JobBuilder.newJob(SimpleJob.class) .withIdentity("myJob", "group1") + .usingJobData("jobSays", "Hello World!") + .usingJobData("myFloatValue", 3.141f) .build(); Trigger trigger = TriggerBuilder.newTrigger() @@ -30,8 +32,36 @@ public class QuartzExample { .withIntervalInSeconds(40) .repeatForever()) .build(); + + JobDetail jobA = JobBuilder.newJob(JobA.class) + .withIdentity("jobA", "group2") + .build(); + + JobDetail jobB = JobBuilder.newJob(JobB.class) + .withIdentity("jobB", "group2") + .build(); + + Trigger triggerA = TriggerBuilder.newTrigger() + .withIdentity("triggerA", "group2") + .startNow() + .withPriority(15) + .withSchedule(SimpleScheduleBuilder.simpleSchedule() + .withIntervalInSeconds(40) + .repeatForever()) + .build(); + + Trigger triggerB = TriggerBuilder.newTrigger() + .withIdentity("triggerB", "group2") + .startNow() + .withPriority(10) + .withSchedule(SimpleScheduleBuilder.simpleSchedule() + .withIntervalInSeconds(20) + .repeatForever()) + .build(); sched.scheduleJob(job, trigger); + sched.scheduleJob(jobA, triggerA); + sched.scheduleJob(jobB, triggerB); sched.start(); } catch (SchedulerException e) { diff --git a/libraries/src/main/java/com/baeldung/quartz/SimpleJob.java b/libraries/src/main/java/com/baeldung/quartz/SimpleJob.java index 370d698d13..986c5e96e5 100644 --- a/libraries/src/main/java/com/baeldung/quartz/SimpleJob.java +++ b/libraries/src/main/java/com/baeldung/quartz/SimpleJob.java @@ -1,13 +1,21 @@ package com.baeldung.quartz; import org.quartz.Job; +import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class SimpleJob implements Job { - public void execute(JobExecutionContext arg0) throws JobExecutionException { - System.out.println("This is a quartz job!"); + public void execute(JobExecutionContext context) throws JobExecutionException { + JobDataMap dataMap = context.getJobDetail() + .getJobDataMap(); + + String jobSays = dataMap.getString("jobSays"); + float myFloatValue = dataMap.getFloat("myFloatValue"); + + System.out.println("Job says: " + jobSays + ", and val is: " + myFloatValue); + } } \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/commons/beanutils/CourseServiceTest.java b/libraries/src/test/java/com/baeldung/commons/beanutils/CourseServiceTest.java new file mode 100644 index 0000000000..d2ae6d7d55 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/beanutils/CourseServiceTest.java @@ -0,0 +1,38 @@ +package com.baeldung.commons.beanutils; + +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class CourseServiceTest { + + @Test + public void givenCourse_whenSetValuesUsingPropertyUtil_thenReturnSetValues() + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + Course course = new Course(); + String name = "Computer Science"; + List codes = Arrays.asList("CS", "CS01"); + CourseService.setValues(course, name, codes); + + Assert.assertEquals(name, course.getName()); + Assert.assertEquals(2, course.getCodes().size()); + Assert.assertEquals("CS", course.getCodes().get(0)); + + CourseService.setIndexedValue(course, 1, "CS02"); + Assert.assertEquals("CS02", course.getCodes().get(1)); + + Student student = new Student(); + String studentName = "Joe"; + student.setName(studentName); + + CourseService.setMappedValue(course, "ST-1", student); + Assert.assertEquals(student, course.getEnrolledStudent("ST-1")); + + String accessedStudentName = CourseService.getNestedValue(course, "ST-1", "name"); + Assert.assertEquals(studentName, accessedStudentName); + } + +} diff --git a/libraries/src/test/java/com/baeldung/commons/collections/orderedmap/OrderedMapUnitTest.java b/libraries/src/test/java/com/baeldung/commons/collections/orderedmap/OrderedMapUnitTest.java new file mode 100644 index 0000000000..5392daea3b --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/collections/orderedmap/OrderedMapUnitTest.java @@ -0,0 +1,201 @@ +package com.baeldung.commons.collections.orderedmap; + +import org.apache.commons.collections4.OrderedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.map.LinkedMap; +import org.apache.commons.collections4.map.ListOrderedMap; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class OrderedMapUnitTest { + + private String[] names = {"Emily", "Mathew", "Rose", "John", "Anna"}; + private Integer[] ages = {37, 28, 40, 36, 21}; + + private int RUNNERS_COUNT = names.length; + + private OrderedMap runnersLinkedMap; + private OrderedMap runnersListOrderedMap; + + @Before + public void createRunners() { + // First implementation: ListOrderedMap + this.runnersListOrderedMap = new ListOrderedMap<>(); + this.loadOrderedMapOfRunners(this.runnersListOrderedMap); + + // Second implementation: LinkedMap + this.runnersLinkedMap = new LinkedMap<>(); + this.loadOrderedMapOfRunners(this.runnersLinkedMap); + } + + private void loadOrderedMapOfRunners(OrderedMap runners) { + for (int i = 0; i < RUNNERS_COUNT; i++) { + runners.put(this.names[i], this.ages[i]); + } + } + + @Test + public void givenALinkedMap_whenIteratedWithMapIterator_thenPreservesOrder() { + // Tests that the order in map iterator is the same + // as defined in the constant arrays of names and ages: + + OrderedMapIterator runnersIterator = this.runnersLinkedMap.mapIterator(); + for (int i = 0; runnersIterator.hasNext(); i++) { + runnersIterator.next(); + + assertEquals(runnersIterator.getKey(), this.names[i]); + assertEquals(runnersIterator.getValue(), this.ages[i]); + } + } + + @Test + public void givenAListOrderedMap_whenIteratedWithMapIterator_thenPreservesOrder() { + // Tests that the order in map iterator is the same + // as defined in the constant arrays of names and ages: + + OrderedMapIterator runnersIterator = this.runnersListOrderedMap.mapIterator(); + for (int i = 0; runnersIterator.hasNext(); i++) { + runnersIterator.next(); + + assertEquals(runnersIterator.getKey(), this.names[i]); + assertEquals(runnersIterator.getValue(), this.ages[i]); + } + } + + @Test + public void givenALinkedMap_whenIteratedForwards_thenPreservesOrder() { + // Tests that the order in the forward iteration is the same + // as defined in the constant arrays of names and ages + + String name = this.runnersLinkedMap.firstKey(); + for (int i = 0; name != null; i++) { + assertEquals(name, this.names[i]); + name = this.runnersLinkedMap.nextKey(name); + } + } + + @Test + public void givenAListOrderedMap_whenIteratedForwards_thenPreservesOrder() { + // Tests that the order in the forward iteration is the same + // as defined in the constant arrays of names and ages + + String name = this.runnersListOrderedMap.firstKey(); + for (int i = 0; name != null; i++) { + assertEquals(name, this.names[i]); + name = this.runnersListOrderedMap.nextKey(name); + } + } + + @Test + public void givenALinkedMap_whenIteratedBackwards_thenPreservesOrder() { + // Tests that the order in the backwards iteration is the same + // as defined in the constant arrays of names and ages + + String name = this.runnersLinkedMap.lastKey(); + for (int i = RUNNERS_COUNT - 1; name != null; i--) { + assertEquals(name, this.names[i]); + name = this.runnersLinkedMap.previousKey(name); + } + } + + @Test + public void givenAListOrderedMap_whenIteratedBackwards_thenPreservesOrder() { + // Tests that the order in the backwards iteration is the same + // as defined in the constant arrays of names and ages + + String name = this.runnersListOrderedMap.lastKey(); + for (int i = RUNNERS_COUNT - 1; name != null; i--) { + assertEquals(name, this.names[i]); + name = this.runnersListOrderedMap.previousKey(name); + } + } + + @Test + public void givenALinkedMap_whenObjectIsSearched_thenMatchesConstantArray() { + assertEquals(ages[4], this.runnersLinkedMap.get("Anna")); + } + + @Test + public void givenALinkedMap_whenConvertedToList_thenMatchesKeySet() { + // Casting the OrderedMap to a LinkedMap we can use asList() method + + LinkedMap lmap = (LinkedMap) this.runnersLinkedMap; + List listKeys = new ArrayList<>(); + listKeys.addAll(this.runnersLinkedMap.keySet()); + List linkedMap = lmap.asList(); + assertEquals(listKeys, linkedMap); + } + + @Test + public void givenALinkedMap_whenSearchByIndexIsUsed_thenMatchesConstantArray() { + LinkedMap lmap = (LinkedMap) this.runnersLinkedMap; + + for (int i = 0; i < RUNNERS_COUNT; i++) { + // accessed by index: + String name = lmap.get(i); + assertEquals(name, this.names[i]); + + // index of key concides with position in array + assertEquals(lmap.indexOf(this.names[i]), i); + } + } + + @Test + public void givenALinkedMap_whenElementRemoved_thenSizeDecrease() { + LinkedMap lmap = (LinkedMap) this.runnersLinkedMap; + Integer johnAge = lmap.remove("John");// by object + assertEquals(johnAge, new Integer(36)); + assertEquals(lmap.size(), RUNNERS_COUNT - 1); + + Integer emilyAge = lmap.remove(0);// by index + assertEquals(emilyAge, new Integer(37)); + assertEquals(lmap.size(), RUNNERS_COUNT - 2); + } + + @Test + public void givenAListOrderedMap_whenObjectIsSearched_thenMatchesConstantArray() { + assertEquals(ages[4], this.runnersListOrderedMap.get("Anna")); + } + + @Test + public void givenAListOrderedMap_whenConvertedToList_thenMatchesKeySet() { + ListOrderedMap lomap = (ListOrderedMap) this.runnersListOrderedMap; + List listKeys = new ArrayList<>(); + listKeys.addAll(this.runnersListOrderedMap.keySet()); + List lomapList = lomap.asList(); + assertEquals(listKeys, lomapList); + } + + @Test + public void givenAListOrderedMap_whenSearchByIndexIsUsed_thenMatchesConstantArray() { + ListOrderedMap lomap = (ListOrderedMap) this.runnersListOrderedMap; + + for (int i = 0; i < RUNNERS_COUNT; i++) { + // accessed by index: + String name = lomap.get(i); + assertEquals(name, this.names[i]); + + // index of key concides with position in array + assertEquals(lomap.indexOf(this.names[i]), i); + } + } + + @Test + public void givenAListOrderedMap_whenElementRemoved_thenSizeDecrease() { + ListOrderedMap lomap = (ListOrderedMap) this.runnersListOrderedMap; + + Integer johnAge = lomap.remove("John");// by object + + assertEquals(johnAge, new Integer(36)); + assertEquals(lomap.size(), RUNNERS_COUNT - 1); + + Integer emilyAge = lomap.remove(0);// by index + assertEquals(emilyAge, new Integer(37)); + assertEquals(lomap.size(), RUNNERS_COUNT - 2); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/ArrayUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/ArrayUtilsUnitTest.java index 39f9907316..97db4ddbe4 100644 --- a/libraries/src/test/java/com/baeldung/commons/lang3/ArrayUtilsUnitTest.java +++ b/libraries/src/test/java/com/baeldung/commons/lang3/ArrayUtilsUnitTest.java @@ -2,77 +2,78 @@ package com.baeldung.commons.lang3; import org.apache.commons.lang3.ArrayUtils; import org.junit.Test; -import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; public class ArrayUtilsUnitTest { @Test public void givenArray_whenAddingElementAtSpecifiedPosition_thenCorrect() { - int[] oldArray = { 2, 3, 4, 5 }; + int[] oldArray = {2, 3, 4, 5}; int[] newArray = ArrayUtils.add(oldArray, 0, 1); - int[] expectedArray = { 1, 2, 3, 4, 5 }; + int[] expectedArray = {1, 2, 3, 4, 5}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenAddingElementAtTheEnd_thenCorrect() { - int[] oldArray = { 2, 3, 4, 5 }; + int[] oldArray = {2, 3, 4, 5}; int[] newArray = ArrayUtils.add(oldArray, 1); - int[] expectedArray = { 2, 3, 4, 5, 1 }; + int[] expectedArray = {2, 3, 4, 5, 1}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenAddingAllElementsAtTheEnd_thenCorrect() { - int[] oldArray = { 0, 1, 2 }; + int[] oldArray = {0, 1, 2}; int[] newArray = ArrayUtils.addAll(oldArray, 3, 4, 5); - int[] expectedArray = { 0, 1, 2, 3, 4, 5 }; + int[] expectedArray = {0, 1, 2, 3, 4, 5}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenRemovingElementAtSpecifiedPosition_thenCorrect() { - int[] oldArray = { 1, 2, 3, 4, 5 }; + int[] oldArray = {1, 2, 3, 4, 5}; int[] newArray = ArrayUtils.remove(oldArray, 1); - int[] expectedArray = { 1, 3, 4, 5 }; + int[] expectedArray = {1, 3, 4, 5}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenRemovingAllElementsAtSpecifiedPositions_thenCorrect() { - int[] oldArray = { 1, 2, 3, 4, 5 }; + int[] oldArray = {1, 2, 3, 4, 5}; int[] newArray = ArrayUtils.removeAll(oldArray, 1, 3); - int[] expectedArray = { 1, 3, 5 }; + int[] expectedArray = {1, 3, 5}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenRemovingAnElement_thenCorrect() { - int[] oldArray = { 1, 2, 3, 3, 4 }; + int[] oldArray = {1, 2, 3, 3, 4}; int[] newArray = ArrayUtils.removeElement(oldArray, 3); - int[] expectedArray = { 1, 2, 3, 4 }; + int[] expectedArray = {1, 2, 3, 4}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenRemovingElements_thenCorrect() { - int[] oldArray = { 1, 2, 3, 3, 4 }; + int[] oldArray = {1, 2, 3, 3, 4}; int[] newArray = ArrayUtils.removeElements(oldArray, 2, 3, 5); - int[] expectedArray = { 1, 3, 4 }; + int[] expectedArray = {1, 3, 4}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenRemovingAllElementOccurences_thenCorrect() { - int[] oldArray = { 1, 2, 2, 2, 3 }; + int[] oldArray = {1, 2, 2, 2, 3}; int[] newArray = ArrayUtils.removeAllOccurences(oldArray, 2); - int[] expectedArray = { 1, 3 }; + int[] expectedArray = {1, 3}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenCheckingExistingElement_thenCorrect() { - int[] array = { 1, 3, 5, 7, 9 }; + int[] array = {1, 3, 5, 7, 9}; boolean evenContained = ArrayUtils.contains(array, 2); boolean oddContained = ArrayUtils.contains(array, 7); assertEquals(false, evenContained); @@ -81,57 +82,57 @@ public class ArrayUtilsUnitTest { @Test public void givenArray_whenReversingElementsWithinARange_thenCorrect() { - int[] originalArray = { 1, 2, 3, 4, 5 }; + int[] originalArray = {1, 2, 3, 4, 5}; ArrayUtils.reverse(originalArray, 1, 4); - int[] expectedArray = { 1, 4, 3, 2, 5 }; + int[] expectedArray = {1, 4, 3, 2, 5}; assertArrayEquals(expectedArray, originalArray); } @Test public void givenArray_whenReversingAllElements_thenCorrect() { - int[] originalArray = { 1, 2, 3, 4, 5 }; + int[] originalArray = {1, 2, 3, 4, 5}; ArrayUtils.reverse(originalArray); - int[] expectedArray = { 5, 4, 3, 2, 1 }; + int[] expectedArray = {5, 4, 3, 2, 1}; assertArrayEquals(expectedArray, originalArray); } @Test public void givenArray_whenShiftingElementsWithinARange_thenCorrect() { - int[] originalArray = { 1, 2, 3, 4, 5 }; + int[] originalArray = {1, 2, 3, 4, 5}; ArrayUtils.shift(originalArray, 1, 4, 1); - int[] expectedArray = { 1, 4, 2, 3, 5 }; + int[] expectedArray = {1, 4, 2, 3, 5}; assertArrayEquals(expectedArray, originalArray); } @Test public void givenArray_whenShiftingAllElements_thenCorrect() { - int[] originalArray = { 1, 2, 3, 4, 5 }; + int[] originalArray = {1, 2, 3, 4, 5}; ArrayUtils.shift(originalArray, 1); - int[] expectedArray = { 5, 1, 2, 3, 4 }; + int[] expectedArray = {5, 1, 2, 3, 4}; assertArrayEquals(expectedArray, originalArray); } @Test public void givenArray_whenExtractingElements_thenCorrect() { - int[] oldArray = { 1, 2, 3, 4, 5 }; + int[] oldArray = {1, 2, 3, 4, 5}; int[] newArray = ArrayUtils.subarray(oldArray, 2, 7); - int[] expectedArray = { 3, 4, 5 }; + int[] expectedArray = {3, 4, 5}; assertArrayEquals(expectedArray, newArray); } @Test public void givenArray_whenSwapingElementsWithinARange_thenCorrect() { - int[] originalArray = { 1, 2, 3, 4, 5 }; + int[] originalArray = {1, 2, 3, 4, 5}; ArrayUtils.swap(originalArray, 0, 3, 2); - int[] expectedArray = { 4, 5, 3, 1, 2 }; + int[] expectedArray = {4, 5, 3, 1, 2}; assertArrayEquals(expectedArray, originalArray); } @Test public void givenArray_whenSwapingElementsAtSpecifiedPositions_thenCorrect() { - int[] originalArray = { 1, 2, 3, 4, 5 }; + int[] originalArray = {1, 2, 3, 4, 5}; ArrayUtils.swap(originalArray, 0, 3); - int[] expectedArray = { 4, 2, 3, 1, 5 }; + int[] expectedArray = {4, 2, 3, 1, 5}; assertArrayEquals(expectedArray, originalArray); } } diff --git a/libraries/src/test/java/com/baeldung/commons/math/ComplexUnitTest.java b/libraries/src/test/java/com/baeldung/commons/math/ComplexUnitTest.java index b10086eabe..ae92617849 100644 --- a/libraries/src/test/java/com/baeldung/commons/math/ComplexUnitTest.java +++ b/libraries/src/test/java/com/baeldung/commons/math/ComplexUnitTest.java @@ -8,7 +8,7 @@ public class ComplexUnitTest { @Test public void whenComplexPow_thenCorrect() { - Complex first = new Complex(1.0, 3.0); + Complex first = new Complex(1.0, 3.0); Complex second = new Complex(2.0, 5.0); Complex power = first.pow(second); diff --git a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java b/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java index a5613e2406..f864c5f017 100644 --- a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java @@ -35,9 +35,9 @@ public class WordCountIntegrationTest { //then List> collect = result.collect(); assertThat(collect).containsExactlyInAnyOrder( - new Tuple2<>("a", 3), new Tuple2<>("sentence", 2), new Tuple2<>("word", 1), - new Tuple2<>("is", 2), new Tuple2<>("this", 2), new Tuple2<>("second", 1), - new Tuple2<>("first", 1), new Tuple2<>("with", 1), new Tuple2<>("one", 1)); + new Tuple2<>("a", 3), new Tuple2<>("sentence", 2), new Tuple2<>("word", 1), + new Tuple2<>("is", 2), new Tuple2<>("this", 2), new Tuple2<>("second", 1), + new Tuple2<>("first", 1), new Tuple2<>("with", 1), new Tuple2<>("one", 1)); } @Test @@ -48,9 +48,9 @@ public class WordCountIntegrationTest { //when List collect = amounts - .filter(a -> a > threshold) - .reduce((integer, t1) -> integer + t1) - .collect(); + .filter(a -> a > threshold) + .reduce((integer, t1) -> integer + t1) + .collect(); //then assertThat(collect.get(0)).isEqualTo(90); @@ -78,13 +78,13 @@ public class WordCountIntegrationTest { Tuple2 fourthPerson = new Tuple2<>(200, "Michael"); Tuple2 firstPerson = new Tuple2<>(1, "Jack"); DataSet> transactions = env.fromElements(fourthPerson, secondPerson, - thirdPerson, firstPerson); + thirdPerson, firstPerson); //when List> sorted = transactions - .sortPartition(new IdKeySelectorTransaction(), Order.ASCENDING) - .collect(); + .sortPartition(new IdKeySelectorTransaction(), Order.ASCENDING) + .collect(); //then assertThat(sorted).containsExactly(firstPerson, secondPerson, thirdPerson, fourthPerson); @@ -99,15 +99,15 @@ public class WordCountIntegrationTest { Tuple2 firstTransaction = new Tuple2<>(1, "Transaction_1"); DataSet> transactions = - env.fromElements(firstTransaction, new Tuple2<>(12, "Transaction_2")); + env.fromElements(firstTransaction, new Tuple2<>(12, "Transaction_2")); //when List, Tuple3>> joined = - transactions.join(addresses) - .where(new IdKeySelectorTransaction()) - .equalTo(new IdKeySelectorAddress()) - .collect(); + transactions.join(addresses) + .where(new IdKeySelectorTransaction()) + .equalTo(new IdKeySelectorAddress()) + .collect(); //then assertThat(joined).hasSize(1); @@ -121,7 +121,7 @@ public class WordCountIntegrationTest { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStream text - = env.fromElements("This is a first sentence", "This is a second sentence with a one word"); + = env.fromElements("This is a first sentence", "This is a second sentence with a one word"); SingleOutputStreamOperator upperCase = text.map(String::toUpperCase); @@ -139,8 +139,8 @@ public class WordCountIntegrationTest { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); SingleOutputStreamOperator> windowed = env.fromElements( - new Tuple2<>(16, ZonedDateTime.now().plusMinutes(25).toInstant().getEpochSecond()), - new Tuple2<>(15, ZonedDateTime.now().plusMinutes(2).toInstant().getEpochSecond()) + new Tuple2<>(16, ZonedDateTime.now().plusMinutes(25).toInstant().getEpochSecond()), + new Tuple2<>(15, ZonedDateTime.now().plusMinutes(2).toInstant().getEpochSecond()) ).assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor>(Time.seconds(20)) { @Override public long extractTimestamp(Tuple2 element) { @@ -149,8 +149,8 @@ public class WordCountIntegrationTest { }); SingleOutputStreamOperator> reduced = windowed - .windowAll(TumblingEventTimeWindows.of(Time.seconds(5))) - .maxBy(0, true); + .windowAll(TumblingEventTimeWindows.of(Time.seconds(5))) + .maxBy(0, true); reduced.print(); diff --git a/libraries/src/test/java/com/baeldung/hikaricp/HikariCPUnitTest.java b/libraries/src/test/java/com/baeldung/hikaricp/HikariCPUnitTest.java index 0e29e3390a..1a1c5ef868 100644 --- a/libraries/src/test/java/com/baeldung/hikaricp/HikariCPUnitTest.java +++ b/libraries/src/test/java/com/baeldung/hikaricp/HikariCPUnitTest.java @@ -1,9 +1,9 @@ package com.baeldung.hikaricp; -import java.util.List; - import org.junit.Test; +import java.util.List; + import static org.junit.Assert.assertEquals; public class HikariCPUnitTest { diff --git a/libraries/src/test/java/com/baeldung/javassist/JavasisstUnitTest.java b/libraries/src/test/java/com/baeldung/javassist/JavasisstUnitTest.java index dd1d1dbcf3..30c034aa5e 100644 --- a/libraries/src/test/java/com/baeldung/javassist/JavasisstUnitTest.java +++ b/libraries/src/test/java/com/baeldung/javassist/JavasisstUnitTest.java @@ -4,7 +4,15 @@ package com.baeldung.javassist; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.NotFoundException; -import javassist.bytecode.*; +import javassist.bytecode.AccessFlag; +import javassist.bytecode.BadBytecode; +import javassist.bytecode.Bytecode; +import javassist.bytecode.ClassFile; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.CodeIterator; +import javassist.bytecode.FieldInfo; +import javassist.bytecode.MethodInfo; +import javassist.bytecode.Mnemonic; import org.junit.Test; import java.io.DataOutputStream; @@ -66,7 +74,7 @@ public class JavasisstUnitTest { //then assertEquals(operations, - Arrays.asList("aload_0", "iload_1", "putfield", "aload_0", "iload_2", "putfield", "return")); + Arrays.asList("aload_0", "iload_1", "putfield", "aload_0", "iload_2", "putfield", "return")); } @@ -112,7 +120,7 @@ public class JavasisstUnitTest { } assertEquals(operations, - Arrays.asList("aload_0", "invokespecial", "return")); + Arrays.asList("aload_0", "invokespecial", "return")); } diff --git a/libraries/src/test/java/com/baeldung/javatuples/JavaTuplesUnitTest.java b/libraries/src/test/java/com/baeldung/javatuples/JavaTuplesUnitTest.java index c99b4d28a2..a341d5957a 100644 --- a/libraries/src/test/java/com/baeldung/javatuples/JavaTuplesUnitTest.java +++ b/libraries/src/test/java/com/baeldung/javatuples/JavaTuplesUnitTest.java @@ -1,10 +1,5 @@ package com.baeldung.javatuples; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Arrays; -import java.util.List; - import org.javatuples.KeyValue; import org.javatuples.LabelValue; import org.javatuples.Pair; @@ -13,6 +8,11 @@ import org.javatuples.Triplet; import org.javatuples.Unit; import org.junit.Test; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + public class JavaTuplesUnitTest { @SuppressWarnings("unused") @@ -26,7 +26,7 @@ public class JavaTuplesUnitTest { Pair pairFromList = Pair.fromIterable(collectionOfNames, 2); - String[] names = new String[] { "john", "doe", "anne" }; + String[] names = new String[]{"john", "doe", "anne"}; Triplet triplet2 = Triplet.fromArray(names); } diff --git a/libraries/src/test/java/com/baeldung/javers/JaversUnitTest.java b/libraries/src/test/java/com/baeldung/javers/JaversUnitTest.java index f261174062..3cdb833953 100644 --- a/libraries/src/test/java/com/baeldung/javers/JaversUnitTest.java +++ b/libraries/src/test/java/com/baeldung/javers/JaversUnitTest.java @@ -74,11 +74,11 @@ public class JaversUnitTest { Javers javers = JaversBuilder.javers().build(); PersonWithAddress person = - new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England"))); + new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England"))); PersonWithAddress personWithNewAddress = - new PersonWithAddress(1, "Tom", - Arrays.asList(new Address("England"), new Address("USA"))); + new PersonWithAddress(1, "Tom", + Arrays.asList(new Address("England"), new Address("USA"))); //when @@ -96,10 +96,10 @@ public class JaversUnitTest { Javers javers = JaversBuilder.javers().build(); PersonWithAddress person = - new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England"))); + new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England"))); PersonWithAddress personWithNewAddress = - new PersonWithAddress(1, "Tom", Collections.emptyList()); + new PersonWithAddress(1, "Tom", Collections.emptyList()); //when diff --git a/libraries/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java b/libraries/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java index 65f89d75b2..578f9ff902 100644 --- a/libraries/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java @@ -24,14 +24,14 @@ public class GuideToJDOIntegrationTest { pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:h2:mem:mypersistence"); pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa"); pumd.addProperty("javax.jdo.option.ConnectionPassword", ""); - pumd.addProperty("datanucleus.autoCreateSchema", "true"); + pumd.addProperty("datanucleus.autoCreateSchema", "true"); PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(pumd, null); PersistenceManager pm = pmf.getPersistenceManager(); Transaction tx = pm.currentTransaction(); try { tx.begin(); - for (int i = 0; i < 100; i++){ + for (int i = 0; i < 100; i++) { String nam = "Product-" + i; Product productx = new Product(nam, (double) i); pm.makePersistent(productx); @@ -58,7 +58,7 @@ public class GuideToJDOIntegrationTest { pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:h2:mem:mypersistence"); pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa"); pumd.addProperty("javax.jdo.option.ConnectionPassword", ""); - pumd.addProperty("datanucleus.autoCreateSchema", "true"); + pumd.addProperty("datanucleus.autoCreateSchema", "true"); PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(pumd, null); PersistenceManager pm = pmf.getPersistenceManager(); @@ -93,9 +93,7 @@ public class GuideToJDOIntegrationTest { Query q = pm2.newQuery("SELECT FROM " + Product.class.getName() + " WHERE price == 200"); @SuppressWarnings("unchecked") List products = (List) q.execute(); - Iterator iter = products.iterator(); - while (iter.hasNext()) { - Product p = iter.next(); + for (Product p : products) { assertEquals("Laptop", p.name); } diff --git a/libraries/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java b/libraries/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java index 38595e49d9..bdbc101b15 100644 --- a/libraries/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java +++ b/libraries/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java @@ -1,8 +1,6 @@ package com.baeldung.jsonassert; -import static org.assertj.core.api.Assertions.assertThat; - import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; @@ -13,6 +11,8 @@ import org.skyscreamer.jsonassert.RegularExpressionValueMatcher; import org.skyscreamer.jsonassert.comparator.ArraySizeComparator; import org.skyscreamer.jsonassert.comparator.CustomComparator; +import static org.assertj.core.api.Assertions.assertThat; + public class JsonAssertUnitTest { @Test @@ -44,7 +44,7 @@ public class JsonAssertUnitTest { @Test public void givenDifferentOrderForJsonObject_whenAssertEquals_thenPass() throws JSONException { String result = "{id:1,name:\"John\"}"; - + JSONAssert.assertEquals("{name:\"John\",id:1}", result, JSONCompareMode.STRICT); JSONAssert.assertEquals("{name:\"John\",id:1}", result, JSONCompareMode.LENIENT); } @@ -55,7 +55,7 @@ public class JsonAssertUnitTest { JSONObject actual = new JSONObject(); expected.put("id", Integer.valueOf(12345)); actual.put("id", Double.valueOf(12345)); - + JSONAssert.assertEquals(expected, actual, false); JSONAssert.assertEquals(expected, actual, JSONCompareMode.LENIENT); } @@ -63,11 +63,11 @@ public class JsonAssertUnitTest { @Test public void givenNestedObjects_whenAssertEquals_thenPass() throws JSONException { String result = "{id:1,name:\"Juergen\", address:{city:\"Hollywood\", " - + "state:\"LA\", zip:91601}}"; + + "state:\"LA\", zip:91601}}"; JSONAssert.assertEquals("{id:1,name:\"Juergen\", address:{city:\"Hollywood\", " - + "state:\"LA\", zip:91601}}", result, false); + + "state:\"LA\", zip:91601}}", result, false); } - + @Test public void whenMessageUsedInAssertion_thenDisplayMessageOnFailure() throws JSONException { String actual = "{id:123,name:\"John\"}"; @@ -94,36 +94,36 @@ public class JsonAssertUnitTest { JSONAssert.assertNotEquals("[1,2,3]", result, JSONCompareMode.LENIENT); JSONAssert.assertNotEquals("[1,2,3,4,5,6]", result, JSONCompareMode.LENIENT); } - + @Test public void whenComparingSizeOfArray_thenPass() throws JSONException { String names = "{names:[Alex, Barbera, Charlie, Xavier]}"; JSONAssert.assertEquals( - "{names:[4]}", - names, - new ArraySizeComparator(JSONCompareMode.LENIENT)); + "{names:[4]}", + names, + new ArraySizeComparator(JSONCompareMode.LENIENT)); } - + @Test public void whenComparingContentsOfArray_thenPass() throws JSONException { String ratings = "{ratings:[3.2,3.5,4.1,5,1]}"; JSONAssert.assertEquals( - "{ratings:[1,5]}", - ratings, - new ArraySizeComparator(JSONCompareMode.LENIENT)); + "{ratings:[1,5]}", + ratings, + new ArraySizeComparator(JSONCompareMode.LENIENT)); } - + @Test public void givenValueMatcher_whenComparingUsingRegex_thenPass() throws IllegalArgumentException, JSONException { - JSONAssert.assertEquals("{entry:{id:x}}", "{entry:{id:1, id:2}}", - new CustomComparator( - JSONCompareMode.STRICT, - new Customization("entry.id", - new RegularExpressionValueMatcher("\\d")))); - - JSONAssert.assertNotEquals("{entry:{id:x}}", "{entry:{id:1, id:as}}", - new CustomComparator(JSONCompareMode.STRICT, - new Customization("entry.id", - new RegularExpressionValueMatcher("\\d")))); + JSONAssert.assertEquals("{entry:{id:x}}", "{entry:{id:1, id:2}}", + new CustomComparator( + JSONCompareMode.STRICT, + new Customization("entry.id", + new RegularExpressionValueMatcher("\\d")))); + + JSONAssert.assertNotEquals("{entry:{id:x}}", "{entry:{id:1, id:as}}", + new CustomComparator(JSONCompareMode.STRICT, + new Customization("entry.id", + new RegularExpressionValueMatcher("\\d")))); } } diff --git a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java index c9141a6e57..1c95956761 100644 --- a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java +++ b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java @@ -1,13 +1,12 @@ package com.baeldung.junitparams; -import static org.junit.Assert.*; - -import org.junit.Test; -import org.junit.runner.RunWith; - import junitparams.FileParameters; import junitparams.JUnitParamsRunner; import junitparams.Parameters; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; @RunWith(JUnitParamsRunner.class) public class SafeAdditionUtilTest { @@ -15,7 +14,7 @@ public class SafeAdditionUtilTest { private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil(); @Test - @Parameters({ "1, 2, 3", "-10, 30, 20", "15, -5, 10", "-5, -10, -15" }) + @Parameters({"1, 2, 3", "-10, 30, 20", "15, -5, 10", "-5, -10, -15"}) public void whenCalledWithAnnotationProvidedParams_thenSafeAddAndReturn(int a, int b, int expectedValue) { assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); } @@ -27,7 +26,7 @@ public class SafeAdditionUtilTest { } private Object[] parametersToTestAdd() { - return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; + return new Object[]{new Object[]{1, 2, 3}, new Object[]{-10, 30, 20}, new Object[]{Integer.MAX_VALUE, 2, Integer.MAX_VALUE}, new Object[]{Integer.MIN_VALUE, -8, Integer.MIN_VALUE}}; } @Test @@ -37,7 +36,7 @@ public class SafeAdditionUtilTest { } private Object[] parametersForWhenCalledWithnoParam_thenLoadByNameSafeAddAndReturn() { - return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; + return new Object[]{new Object[]{1, 2, 3}, new Object[]{-10, 30, 20}, new Object[]{Integer.MAX_VALUE, 2, Integer.MAX_VALUE}, new Object[]{Integer.MIN_VALUE, -8, Integer.MIN_VALUE}}; } @Test diff --git a/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java b/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java index d318345a56..08a472502e 100644 --- a/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java +++ b/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java @@ -3,11 +3,11 @@ package com.baeldung.junitparams; public class TestDataProvider { public static Object[] provideBasicData() { - return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { 15, -5, 10 }, new Object[] { -5, -10, -15 } }; + return new Object[]{new Object[]{1, 2, 3}, new Object[]{-10, 30, 20}, new Object[]{15, -5, 10}, new Object[]{-5, -10, -15}}; } public static Object[] provideEdgeCaseData() { - return new Object[] { new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -2, Integer.MIN_VALUE }, }; + return new Object[]{new Object[]{Integer.MAX_VALUE, 2, Integer.MAX_VALUE}, new Object[]{Integer.MIN_VALUE, -2, Integer.MIN_VALUE},}; } } diff --git a/libraries/src/test/java/com/baeldung/lsh/LocalSensitiveHashingUnitTest.java b/libraries/src/test/java/com/baeldung/lsh/LocalSensitiveHashingUnitTest.java new file mode 100644 index 0000000000..fbcda2a70d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/lsh/LocalSensitiveHashingUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.lsh; + +import info.debatty.java.lsh.LSHMinHash; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class LocalSensitiveHashingUnitTest { + + @Ignore("for simplicity of the example number of input vectors is very low, that's why LSH may yield non deterministic results") + @Test() + public void givenNVectors_whenPerformLSH_thenShouldCalculateSameHashForSimilarVectors() { + //given + boolean[] vector1 = new boolean[]{true, true, true, true, true}; + boolean[] vector2 = new boolean[]{false, false, false, true, false}; + boolean[] vector3 = new boolean[]{false, false, true, true, false}; + + int sizeOfVectors = 5; + int numberOfBuckets = 10; + int stages = 4; + + LSHMinHash lsh = new LSHMinHash(stages, numberOfBuckets, sizeOfVectors); + + //when + int[] firstHash = lsh.hash(vector1); + int[] secondHash = lsh.hash(vector2); + int[] thirdHash = lsh.hash(vector3); + + System.out.println(Arrays.toString(firstHash)); + System.out.println(Arrays.toString(secondHash)); + System.out.println(Arrays.toString(thirdHash)); + + //then + int lastIndexOfResult = stages - 1; + assertThat(firstHash[lastIndexOfResult]).isNotEqualTo(secondHash[lastIndexOfResult]); + assertThat(firstHash[lastIndexOfResult]).isNotEqualTo(thirdHash[lastIndexOfResult]); + assertThat(isCloseOrEqual(secondHash[lastIndexOfResult], thirdHash[lastIndexOfResult], numberOfBuckets)).isTrue(); + } + + private boolean isCloseOrEqual(int secondHash, int thirdHash, int numberOfBuckets) { + return Math.abs(secondHash - thirdHash) < numberOfBuckets / 2; + } +} + diff --git a/libraries/src/test/java/com/baeldung/opennlp/OpenNLPTests.java b/libraries/src/test/java/com/baeldung/opennlp/OpenNLPTests.java index a38791fd61..38bc8e002b 100644 --- a/libraries/src/test/java/com/baeldung/opennlp/OpenNLPTests.java +++ b/libraries/src/test/java/com/baeldung/opennlp/OpenNLPTests.java @@ -1,15 +1,5 @@ package com.baeldung.opennlp; -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import org.junit.Test; - import opennlp.tools.chunker.ChunkerME; import opennlp.tools.chunker.ChunkerModel; import opennlp.tools.cmdline.postag.POSModelLoader; @@ -31,14 +21,23 @@ import opennlp.tools.util.ObjectStream; import opennlp.tools.util.PlainTextByLineStream; import opennlp.tools.util.Span; import opennlp.tools.util.TrainingParameters; +import org.junit.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.Assert.assertEquals; public class OpenNLPTests { private final static String text = "To get to the south: Go to the store. Buy a compass. Use the compass. Then walk to the south."; - private final static String sentence[] = new String[] { "James", "Jordan", "live", "in", "Oklahoma", "city", "." }; - + private final static String sentence[] = new String[]{"James", "Jordan", "live", "in", "Oklahoma", "city", "."}; + @Test - public void givenText_WhenDetectSentences_ThenCountSentences(){ + public void givenText_WhenDetectSentences_ThenCountSentences() { InputStream is; SentenceModel model; try { @@ -48,15 +47,13 @@ public class OpenNLPTests { String sentences[] = sdetector.sentDetect(text); assertEquals(4, sentences.length); is.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Test - public void givenText_WhenDetectTokens_ThenVerifyNames(){ + public void givenText_WhenDetectTokens_ThenVerifyNames() { InputStream is; TokenNameFinderModel model; try { @@ -68,15 +65,13 @@ public class OpenNLPTests { String[] names = Span.spansToStrings(nameSpans, sentence); assertEquals(1, names.length); assertEquals("James Jordan", names[0]); - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Test - public void givenText_WhenDetectTokens_ThenVerifyLocations(){ + public void givenText_WhenDetectTokens_ThenVerifyLocations() { InputStream is; TokenNameFinderModel model; try { @@ -88,15 +83,13 @@ public class OpenNLPTests { String[] locations = Span.spansToStrings(locationSpans, sentence); assertEquals(1, locations.length); assertEquals("Oklahoma", locations[0]); - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } - + @Test - public void givenText_WhenCategorizeDocument_ThenVerifyDocumentContent(){ + public void givenText_WhenCategorizeDocument_ThenVerifyDocumentContent() { DoccatModel docCatModel; try { InputStreamFactory isf = new InputStreamFactory() { @@ -118,7 +111,7 @@ public class OpenNLPTests { } @Test - public void givenText_WhenTagDocument_ThenVerifyTaggedString(){ + public void givenText_WhenTagDocument_ThenVerifyTaggedString() { try { POSModel posModel = new POSModelLoader().load(new File("OpenNLP/en-pos-maxent.bin")); POSTaggerME posTaggerME = new POSTaggerME(posModel); @@ -140,19 +133,19 @@ public class OpenNLPTests { e.printStackTrace(); } } - + @Test - public void givenText_WhenChunked_ThenCountChunks(){ + public void givenText_WhenChunked_ThenCountChunks() { try { InputStream is = new FileInputStream("OpenNLP/en-chunker.bin"); ChunkerModel cModel = new ChunkerModel(is); ChunkerME chunkerME = new ChunkerME(cModel); - String pos[] = new String[] { "NNP", "NNP", "NNP", "POS", "NNP", "NN", "VBD"}; + String pos[] = new String[]{"NNP", "NNP", "NNP", "POS", "NNP", "NN", "VBD"}; String chunks[] = chunkerME.chunk(sentence, pos); assertEquals(7, chunks.length); } catch (IOException e) { e.printStackTrace(); } } - + } diff --git a/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java index bfec945e63..09db11a184 100644 --- a/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java @@ -2,9 +2,6 @@ package com.baeldung.serenity; import net.serenitybdd.jbehave.SerenityStory; -/** - * @author aiet - */ public class GithubUserProfilePayloadIntegrationTest extends SerenityStory { } diff --git a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java b/libraries/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java index 5fcd1bd458..1ebbd49e79 100644 --- a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java @@ -13,13 +13,11 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; -/** - * @author aiet - */ @RunWith(SerenityRunner.class) public class GoogleSearchLiveTest { - @Managed(driver = "chrome") private WebDriver browser; + @Managed(driver = "chrome") + private WebDriver browser; @Test public void whenGoogleBaeldungThenShouldSeeEugen() { diff --git a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java b/libraries/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java index 1018281687..47fcdd5403 100644 --- a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java @@ -7,15 +7,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.WebDriver; -/** - * @author aiet - */ @RunWith(SerenityRunner.class) public class GoogleSearchPageObjectLiveTest { - @Managed(driver = "chrome") private WebDriver browser; + @Managed(driver = "chrome") + private WebDriver browser; - GoogleSearchPageObject googleSearch; + private GoogleSearchPageObject googleSearch; @Test public void whenGoogleBaeldungThenShouldSeeEugen() { diff --git a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java b/libraries/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java index e07c82943c..63a70ddff4 100644 --- a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java @@ -12,19 +12,20 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.WebDriver; -import static net.serenitybdd.screenplay.GivenWhenThen.*; +import static net.serenitybdd.screenplay.GivenWhenThen.givenThat; +import static net.serenitybdd.screenplay.GivenWhenThen.seeThat; +import static net.serenitybdd.screenplay.GivenWhenThen.then; +import static net.serenitybdd.screenplay.GivenWhenThen.when; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; -/** - * Unit test for simple App. - */ @RunWith(SerenityRunner.class) public class GoogleSearchScreenplayLiveTest { - @Managed(driver = "chrome") WebDriver browser; + @Managed(driver = "chrome") + private WebDriver browser; - Actor kitty = Actor.named("kitty"); + private Actor kitty = Actor.named("kitty"); @Before public void setup() { diff --git a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java index 30faf92c6e..18488f9380 100644 --- a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java @@ -16,7 +16,8 @@ import static com.baeldung.serenity.membership.MemberGrade.Silver; @RunWith(SerenityRunner.class) public class MemberStatusIntegrationTest { - @Steps MemberStatusSteps memberSteps; + @Steps + private MemberStatusSteps memberSteps; @Test public void membersShouldStartWithBronzeStatus() { @@ -42,7 +43,7 @@ public class MemberStatusIntegrationTest { @Test @Title("Members with 50,000 points can exchange a MacBook Pro") - public void memberWith50000PointsCanExchangeAMacbookpro(){ + public void memberWith50000PointsCanExchangeAMacbookpro() { memberSteps.aMemberHasPointsOf(50_000); memberSteps.aMemberExchangeA(MacBookPro); memberSteps.memberShouldHavePointsLeft(); @@ -55,7 +56,7 @@ public class MemberStatusIntegrationTest { @Test @Ignore @Title("Members with 500 points should have a Gold status when added 4,000 points ($40,000)") - public void memberWith500PointsEarnsGoldAfterSpends$40000(){ + public void memberWith500PointsEarnsGoldAfterSpends$40000() { memberSteps.aMemberHasPointsOf(500); memberSteps.theMemberSpends(40_000); memberSteps.theMemberShouldHaveAStatusOf(Gold); @@ -64,7 +65,7 @@ public class MemberStatusIntegrationTest { @Test @Ignore @Title("Members with 100 points would have a Gold status when added 10,000 points ($100,000)") - public void memberWith100EarnsGoldAfterSpends$100000(){ + public void memberWith100EarnsGoldAfterSpends$100000() { memberSteps.aMemberHasPointsOf(100); memberSteps.theMemberSpends(100_000); memberSteps.theMemberShouldHaveAStatusOf(Gold); diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java index cc434d6d19..eba406a8b5 100644 --- a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java +++ b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java @@ -8,25 +8,22 @@ import java.io.IOException; import static net.serenitybdd.rest.SerenityRest.rest; import static net.serenitybdd.rest.SerenityRest.then; -/** - * @author aiet - */ -public class GithubRestAssuredUserAPISteps { +class GithubRestAssuredUserAPISteps { private String api; @Step("Given the github REST API for user profile") - public void withUserProfileAPIEndpoint() { + void withUserProfileAPIEndpoint() { api = "https://api.github.com/users/{username}"; } @Step("When looking for {0} via the api") - public void getProfileOfUser(String username) throws IOException { + void getProfileOfUser(String username) throws IOException { rest().get(api, username); } @Step("Then there should be a login field with value {0} in payload of user {0}") - public void profilePayloadShouldContainLoginValue(String username) { + void profilePayloadShouldContainLoginValue(String username) { then().body("login", Matchers.equalTo(username)); } diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java index 6e7fbace49..2ba5b1c8ed 100644 --- a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java +++ b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java @@ -14,9 +14,6 @@ import java.io.IOException; import static org.hamcrest.MatcherAssert.assertThat; -/** - * @author aiet - */ public class GithubRestUserAPISteps { private String api; diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java b/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java index f3b374b66c..959f462dbd 100644 --- a/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java +++ b/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java @@ -9,11 +9,8 @@ import java.io.IOException; public class GithubUserProfilePayloadStepDefinitions { -// @Steps -// GithubRestUserAPISteps userAPISteps; - @Steps - GithubRestAssuredUserAPISteps userAPISteps; + private GithubRestAssuredUserAPISteps userAPISteps; @Given("github user profile api") public void givenGithubUserProfileApi() { diff --git a/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java b/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java index 02b3f0130e..49ed8cae7d 100644 --- a/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java +++ b/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java @@ -6,12 +6,9 @@ import net.thucydides.core.annotations.Step; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; -/** - * @author aiet - */ public class MemberStatusSteps { - Member member; + private Member member; @Step("Given a member has {0} points") public void aMemberHasPointsOf(int points) { @@ -35,7 +32,7 @@ public class MemberStatusSteps { @Pending @Step("When the member exchange {}") - public void aMemberExchangeA(Commodity commodity){ + public void aMemberExchangeA(Commodity commodity) { //TODO } diff --git a/libraries/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java b/libraries/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java index 72569d86b5..bdba8a69bc 100644 --- a/libraries/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java +++ b/libraries/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java @@ -10,15 +10,14 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; -/** - * @author aiet - */ @DefaultUrl("https://www.google.com/ncr") public class GoogleSearchPageObject extends PageObject { - @FindBy(name = "q") private WebElement search; + @FindBy(name = "q") + private WebElement search; - @FindBy(css = "._ksh") private WebElement result; + @FindBy(css = "._ksh") + private WebElement result; public void searchFor(String keyword) { search.sendKeys(keyword, Keys.ENTER); diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java b/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java index 0573e52ca4..b60c929c05 100644 --- a/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java +++ b/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java @@ -8,13 +8,13 @@ import net.thucydides.core.annotations.DefaultUrl; * @author baoqiang */ @DefaultUrl("https://www.google.com/ncr") -public class GoogleSearchPage extends PageObject { +class GoogleSearchPage extends PageObject { - public static final Target SEARCH_RESULT_TITLES = Target + static final Target SEARCH_RESULT_TITLES = Target .the("search results") .locatedBy("._ksh"); - public static final Target SEARCH_INPUT_BOX = Target + static final Target SEARCH_INPUT_BOX = Target .the("search input box") .locatedBy("#lst-ib"); diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java b/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java index 1cbcb22166..38990e13b6 100644 --- a/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java +++ b/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java @@ -6,9 +6,6 @@ import net.serenitybdd.screenplay.questions.Text; import java.util.List; -/** - * @author baoqiang - */ public class GoogleSearchResults implements Question> { public static Question> displayed() { diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java b/libraries/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java index 2783f14e51..1628ef8ed7 100644 --- a/libraries/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java +++ b/libraries/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java @@ -7,9 +7,6 @@ import net.serenitybdd.screenplay.actions.Enter; import net.thucydides.core.annotations.Step; import org.openqa.selenium.Keys; -/** - * @author baoqiang - */ public class SearchForKeyword implements Task { @Step("{0} searches for '#keyword'") diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/StartWith.java b/libraries/src/test/java/com/baeldung/serenity/screenplay/StartWith.java index ae9de5d798..52c6d07fda 100644 --- a/libraries/src/test/java/com/baeldung/serenity/screenplay/StartWith.java +++ b/libraries/src/test/java/com/baeldung/serenity/screenplay/StartWith.java @@ -7,9 +7,6 @@ import net.thucydides.core.annotations.Step; import static net.serenitybdd.screenplay.Tasks.instrumented; -/** - * @author baoqiang - */ public class StartWith implements Task { public static StartWith googleSearchPage() { diff --git a/libraries/src/test/java/com/baeldung/stm/AccountTest.java b/libraries/src/test/java/com/baeldung/stm/AccountTest.java index d45490df94..be3edf058c 100644 --- a/libraries/src/test/java/com/baeldung/stm/AccountTest.java +++ b/libraries/src/test/java/com/baeldung/stm/AccountTest.java @@ -1,9 +1,7 @@ package com.baeldung.stm; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; diff --git a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java index f35073e9d9..e14a91ce67 100644 --- a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java @@ -17,10 +17,10 @@ public class JoolMergeStreamsTest { Stream seq2 = Stream.of(2, 4, 6); Stream resultingSeq = Seq.ofType(seq1, Integer.class) - .append(seq2); + .append(seq2); assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6), - resultingSeq.collect(Collectors.toList())); + resultingSeq.collect(Collectors.toList())); } @Test @@ -30,10 +30,10 @@ public class JoolMergeStreamsTest { Stream closingBracketSeq = Stream.of("]"); Stream resultingStream = Seq.ofType(seq, String.class) - .append(closingBracketSeq) - .prepend(openingBracketSeq); + .append(closingBracketSeq) + .prepend(openingBracketSeq); Assert.assertEquals(Arrays.asList("[", "foo", "bar", "]"), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } } \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java index 217d2b5b64..23110947b6 100644 --- a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java @@ -17,10 +17,10 @@ public class MergeStreamsTest { Stream stream2 = Stream.of(2, 4, 6); Stream resultingStream = Stream.concat(stream1, - stream2); + stream2); assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } @Test @@ -30,11 +30,11 @@ public class MergeStreamsTest { Stream stream3 = Stream.of(18, 15, 36); Stream resultingStream = Stream.concat(Stream.concat(stream1, - stream2), - stream3); + stream2), + stream3); assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } @Test @@ -47,7 +47,7 @@ public class MergeStreamsTest { Stream resultingStream = Stream.of(stream1, stream2, stream3, stream4).flatMap(Function.identity()); assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } } \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java index 6ac3cc14cb..5104ec0682 100644 --- a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java @@ -19,7 +19,7 @@ public class StreamExMergeStreamsTest { Stream resultingStream = StreamEx.of(stream1).append(stream2); assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } @Test @@ -30,12 +30,12 @@ public class StreamExMergeStreamsTest { Stream stream4 = Stream.of(99); Stream resultingStream = StreamEx.of(stream1) - .append(stream2) - .append(stream3) - .append(stream4); + .append(stream2) + .append(stream3) + .append(stream4); assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } @@ -46,10 +46,10 @@ public class StreamExMergeStreamsTest { Stream closingBracketStream = Stream.of("]"); Stream resultingStream = StreamEx.of(stream1) - .append(closingBracketStream) - .prepend(openingBracketStream); + .append(closingBracketStream) + .prepend(openingBracketStream); assertEquals(Arrays.asList("[", "foo", "bar", "]"), - resultingStream.collect(Collectors.toList())); + resultingStream.collect(Collectors.toList())); } } diff --git a/pom.xml b/pom.xml index 947b4ec441..91d7abd5ca 100644 --- a/pom.xml +++ b/pom.xml @@ -131,6 +131,7 @@ spring-amqp-simple spring-apache-camel spring-batch + spring-bom spring-boot spring-cloud-data-flow spring-cloud diff --git a/spring-5/README.md b/spring-5/README.md index 31f665f4a2..510ee45f03 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -7,3 +7,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests) - [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web) +- [Exploring the Spring MVC URL Matching Improvements](http://www.baeldung.com/spring-mvc-url-matching) diff --git a/spring-5/pom.xml b/spring-5/pom.xml index 605dbe39e1..4b373923ef 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -177,6 +177,7 @@ 1.0.0-M4 5.0.0-M4 2.20 + 5.0.0.RC2 diff --git a/spring-5/src/main/java/com/baeldung/Spring5Application.java b/spring-5/src/main/java/com/baeldung/Spring5Application.java index 41b5c1eed1..aaff1797ff 100644 --- a/spring-5/src/main/java/com/baeldung/Spring5Application.java +++ b/spring-5/src/main/java/com/baeldung/Spring5Application.java @@ -2,8 +2,10 @@ package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; @SpringBootApplication +@ComponentScan(basePackages = {"com.baeldung.web"}) public class Spring5Application { public static void main(String[] args) { diff --git a/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java b/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java new file mode 100644 index 0000000000..b7436c5ba7 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java @@ -0,0 +1,61 @@ +package com.baeldung.functional; + +import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; +import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; +import static org.springframework.web.reactive.function.server.ServerResponse.ok; + +import org.apache.catalina.Context; +import org.apache.catalina.startup.Tomcat; +import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; +import org.springframework.boot.web.server.WebServer; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.WebHandler; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + +public class ExploreSpring5URLPatternUsingRouterFunctions { + + private RouterFunction routingFunction() { + + return route(GET("/p?ths"), serverRequest -> ok().body(fromObject("/p?ths"))).andRoute(GET("/test/{*id}"), serverRequest -> ok().body(fromObject(serverRequest.pathVariable("id")))) + .andRoute(GET("/*card"), serverRequest -> ok().body(fromObject("/*card path was accessed"))) + .andRoute(GET("/{var1}_{var2}"), serverRequest -> ok().body(fromObject(serverRequest.pathVariable("var1") + " , " + serverRequest.pathVariable("var2")))) + .andRoute(GET("/{baeldung:[a-z]+}"), serverRequest -> ok().body(fromObject("/{baeldung:[a-z]+} was accessed and baeldung=" + serverRequest.pathVariable("baeldung")))) + .and(RouterFunctions.resources("/files/{*filepaths}", new ClassPathResource("files/"))); + } + + WebServer start() throws Exception { + WebHandler webHandler = (WebHandler) toHttpHandler(routingFunction()); + HttpHandler httpHandler = WebHttpHandlerBuilder.webHandler(webHandler) + .prependFilter(new IndexRewriteFilter()) + .build(); + + Tomcat tomcat = new Tomcat(); + tomcat.setHostname("localhost"); + tomcat.setPort(9090); + Context rootContext = tomcat.addContext("", System.getProperty("java.io.tmpdir")); + ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler); + Tomcat.addServlet(rootContext, "httpHandlerServlet", servlet); + rootContext.addServletMappingDecoded("/", "httpHandlerServlet"); + + TomcatWebServer server = new TomcatWebServer(tomcat); + server.start(); + return server; + + } + + public static void main(String[] args) { + try { + new FunctionalWebApplication().start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java b/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java index 258a23a2bf..8a808fc83a 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java +++ b/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java @@ -15,6 +15,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import reactor.core.publisher.Flux; @@ -58,7 +59,7 @@ public class FunctionalSpringBootApplication { @Bean public ServletRegistrationBean servletRegistrationBean() throws Exception { HttpHandler httpHandler = WebHttpHandlerBuilder - .webHandler(toHttpHandler(routingFunction())) + .webHandler((WebHandler) toHttpHandler(routingFunction())) .prependFilter(new IndexRewriteFilter()) .build(); ServletRegistrationBean registrationBean = new ServletRegistrationBean<>(new RootServlet(httpHandler), "/"); diff --git a/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java b/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java index 573813b166..29f9ea43da 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java +++ b/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java @@ -50,7 +50,7 @@ public class FunctionalWebApplication { } WebServer start() throws Exception { - WebHandler webHandler = toHttpHandler(routingFunction()); + WebHandler webHandler = (WebHandler) toHttpHandler(routingFunction()); HttpHandler httpHandler = WebHttpHandlerBuilder .webHandler(webHandler) .prependFilter(new IndexRewriteFilter()) diff --git a/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java b/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java index 3e19f81943..d218bba581 100644 --- a/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java +++ b/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java @@ -19,7 +19,7 @@ class IndexRewriteFilter implements WebFilter { .mutate() .request(builder -> builder .method(request.getMethod()) - .contextPath(request.getContextPath()) + .contextPath(request.getPath().toString()) .path("/test")) .build()); } diff --git a/spring-5/src/main/java/com/baeldung/functional/RootServlet.java b/spring-5/src/main/java/com/baeldung/functional/RootServlet.java index 54892c829f..922809e563 100644 --- a/spring-5/src/main/java/com/baeldung/functional/RootServlet.java +++ b/spring-5/src/main/java/com/baeldung/functional/RootServlet.java @@ -23,12 +23,13 @@ import static org.springframework.web.reactive.function.server.RequestPredicates import static org.springframework.web.reactive.function.server.RouterFunctions.route; import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; import static org.springframework.web.reactive.function.server.ServerResponse.ok; +import org.springframework.web.server.WebHandler; public class RootServlet extends ServletHttpHandlerAdapter { public RootServlet() { this(WebHttpHandlerBuilder - .webHandler(toHttpHandler(routingFunction())) + .webHandler((WebHandler) toHttpHandler(routingFunction())) .prependFilter(new IndexRewriteFilter()) .build()); } diff --git a/spring-5/src/main/java/com/baeldung/web/PathPatternController.java b/spring-5/src/main/java/com/baeldung/web/PathPatternController.java new file mode 100644 index 0000000000..15b689257a --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/web/PathPatternController.java @@ -0,0 +1,40 @@ +package com.baeldung.web; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PathPatternController { + + @GetMapping("/spring5/{*id}") + public String URIVariableHandler(@PathVariable String id) { + return id; + } + + @GetMapping("/s?ring5") + public String wildcardTakingExactlyOneChar() { + return "/s?ring5"; + } + + @GetMapping("/spring5/*id") + public String wildcardTakingZeroOrMoreChar() { + return "/spring5/*id"; + } + + @GetMapping("/resources/**") + public String wildcardTakingZeroOrMorePathSegments() { + return "/resources/**"; + } + + @GetMapping("/{baeldung:[a-z]+}") + public String regexInPathVariable(@PathVariable String baeldung) { + return baeldung; + } + + @GetMapping("/{var1}_{var2}") + public String multiplePathVariablesInSameSegment(@PathVariable String var1, @PathVariable String var2) { + return "Two variables are var1=" + var1 + " and var2=" + var2; + } +} diff --git a/spring-5/src/main/resources/files/test/test.txt b/spring-5/src/main/resources/files/test/test.txt new file mode 100644 index 0000000000..30d74d2584 --- /dev/null +++ b/spring-5/src/main/resources/files/test/test.txt @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java index 1ce96de4ef..cbb7a2867b 100644 --- a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java @@ -9,14 +9,14 @@ public class ParallelIntegrationTest { @Test public void runTests() { - final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; + final Class[] classes = {Example1IntegrationTest.class, Example2IntegrationTest.class}; JUnitCore.runClasses(new Computer(), classes); } @Test public void runTestsInParallel() { - final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; + final Class[] classes = {Example1IntegrationTest.class, Example2IntegrationTest.class}; JUnitCore.runClasses(new ParallelComputer(true, true), classes); } diff --git a/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java b/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java index 938ee7fd43..a155de20fa 100644 --- a/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java @@ -15,9 +15,6 @@ import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -/** - * @author aiet - */ @RunWith(SpringRunner.class) @ContextConfiguration(classes = Spring5JUnit4ConcurrentIntegrationTest.SimpleConfiguration.class) public class Spring5JUnit4ConcurrentIntegrationTest implements ApplicationContextAware, InitializingBean { diff --git a/spring-5/src/test/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctionsTest.java b/spring-5/src/test/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctionsTest.java new file mode 100644 index 0000000000..7a38fa697f --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctionsTest.java @@ -0,0 +1,110 @@ +package com.baeldung.functional; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.boot.web.server.WebServer; +import org.springframework.test.web.reactive.server.WebTestClient; + +public class ExploreSpring5URLPatternUsingRouterFunctionsTest { + + private static WebTestClient client; + private static WebServer server; + + @BeforeClass + public static void setup() throws Exception { + server = new ExploreSpring5URLPatternUsingRouterFunctions().start(); + client = WebTestClient.bindToServer() + .baseUrl("http://localhost:" + server.getPort()) + .build(); + } + + @AfterClass + public static void destroy() { + server.stop(); + } + + @Test + public void givenRouter_whenGetPathWithSingleCharWildcard_thenGotPathPattern() throws Exception { + client.get() + .uri("/paths") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("/p?ths"); + } + + @Test + public void givenRouter_whenMultipleURIVariablePattern_thenGotPathVariable() throws Exception { + client.get() + .uri("/test/ab/cd") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("/ab/cd"); + } + + @Test + public void givenRouter_whenGetMultipleCharWildcard_thenGotPathPattern() throws Exception { + + client.get() + .uri("/wildcard") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("/*card path was accessed"); + } + + @Test + public void givenRouter_whenGetMultiplePathVaribleInSameSegment_thenGotPathVariables() throws Exception { + + client.get() + .uri("/baeldung_tutorial") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("baeldung , tutorial"); + } + + @Test + public void givenRouter_whenGetRegexInPathVarible_thenGotPathVariable() throws Exception { + + client.get() + .uri("/abcd") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("/{baeldung:[a-z]+} was accessed and baeldung=abcd"); + + client.get() + .uri("/1234") + .exchange() + .expectStatus() + .is4xxClientError(); + } + + @Test + public void givenResources_whenAccess_thenGot() throws Exception { + client.get() + .uri("/files/test/test.txt") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("test"); + + client.get() + .uri("/files/hello.txt") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("hello"); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java b/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java index cf1029c12f..6f39f11b00 100644 --- a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java @@ -8,7 +8,6 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; - import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.BodyInserters; diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java index b90012edf6..42d27b90f4 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java @@ -16,10 +16,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; class Spring5JUnit5ComposedAnnotationIntegrationTest { @Autowired - Task task; + private Task task; @Autowired - List tasks; + private List tasks; @Test @DisplayName("ApplicationContext injected into method") diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java index f0cc55fc80..0f00a85832 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java @@ -1,7 +1,7 @@ package com.baeldung.jupiter; import com.baeldung.web.reactive.Task; - +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -10,14 +10,12 @@ import org.springframework.test.context.ContextConfiguration; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.jupiter.api.Test; - @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = TestConfig.class) class Spring5JUnit5IntegrationTest { @Autowired - Task task; + private Task task; @Test void givenAMethodName_whenInjecting_thenApplicationContextInjectedIntoMetho(ApplicationContext applicationContext) { diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java index 1794da45f5..fb6bb27684 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java @@ -7,10 +7,10 @@ import org.junit.jupiter.api.Test; import org.junit.runner.Computer; import org.junit.runner.JUnitCore; -public class Spring5JUnit5ParallelIntegrationTest { +class Spring5JUnit5ParallelIntegrationTest { @Test - public void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() { + void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() { final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; @@ -19,7 +19,7 @@ public class Spring5JUnit5ParallelIntegrationTest { } @Test - public void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() { + void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() { final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java index 97efa19255..2c3a71fb3e 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java @@ -1,25 +1,25 @@ package com.baeldung.jupiter; import org.junit.jupiter.api.Test; + import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; + import static org.junit.jupiter.api.Assertions.assertEquals; -public class Spring5Java8NewFeaturesIntegrationTest { +class Spring5Java8NewFeaturesIntegrationTest { @FunctionalInterface public interface FunctionalInterfaceExample { Result reverseString(Input input); } - public class StringUtils{ - public FunctionalInterfaceExample - functionLambdaString = s -> { - return Pattern.compile(" +").splitAsStream(s) - .map(word->new StringBuilder(word).reverse()) + public class StringUtils { + FunctionalInterfaceExample + functionLambdaString = s -> Pattern.compile(" +").splitAsStream(s) + .map(word -> new StringBuilder(word).reverse()) .collect(Collectors.joining(" ")); - }; } @Test diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java index c44728c856..5c289c3e34 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java @@ -3,16 +3,8 @@ package com.baeldung.jupiter; import com.baeldung.web.reactive.Task; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ExchangeFunction; -import org.springframework.web.reactive.function.client.ExchangeFunctions; -import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; @@ -21,10 +13,8 @@ import reactor.core.publisher.Mono; import reactor.ipc.netty.NettyContext; import reactor.ipc.netty.http.server.HttpServer; -import java.net.URI; import java.time.Duration; -import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RequestPredicates.POST; diff --git a/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java b/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java new file mode 100644 index 0000000000..90e3e7c445 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java @@ -0,0 +1,101 @@ +package com.baeldung.web; + +import com.baeldung.Spring5Application; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5Application.class) +public class PathPatternsUsingHandlerMethodIntegrationTest { + + private static WebTestClient client; + + @BeforeClass + public static void setUp() { + client = WebTestClient.bindToController(new PathPatternController()) + .build(); + } + + @Test + public void givenHandlerMethod_whenMultipleURIVariablePattern_then200() { + + client.get() + .uri("/spring5/ab/cd") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/ab/cd"); + } + + @Test + public void givenHandlerMethod_whenURLWithWildcardTakingZeroOrMoreChar_then200() { + + client.get() + .uri("/spring5/userid") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/spring5/*id"); + } + + @Test + public void givenHandlerMethod_whenURLWithWildcardTakingExactlyOneChar_then200() { + + client.get() + .uri("/string5") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/s?ring5"); + } + + @Test + public void givenHandlerMethod_whenURLWithWildcardTakingZeroOrMorePathSegments_then200() { + + client.get() + .uri("/resources/baeldung") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/resources/**"); + } + + @Test + public void givenHandlerMethod_whenURLWithRegexInPathVariable_thenExpectedOutput() { + + client.get() + .uri("/abc") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("abc"); + + client.get() + .uri("/123") + .exchange() + .expectStatus() + .is4xxClientError(); + } + + @Test + public void givenHandlerMethod_whenURLWithMultiplePathVariablesInSameSegment_then200() { + + client.get() + .uri("/baeldung_tutorial") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("Two variables are var1=baeldung and var2=tutorial"); + } + +} diff --git a/spring-bom/README.md b/spring-bom/README.md new file mode 100644 index 0000000000..10e3502d11 --- /dev/null +++ b/spring-bom/README.md @@ -0,0 +1,3 @@ + +### Relevant Articles: +- [Spring with Maven BOM] diff --git a/spring-bom/pom.xml b/spring-bom/pom.xml new file mode 100644 index 0000000000..306632eb21 --- /dev/null +++ b/spring-bom/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + com.baeldung + spring-bom + 1.0.0-SNAPSHOT + spring-bom + http://maven.apache.org + + UTF-8 + + + + + org.springframework + spring-framework-bom + 4.3.8.RELEASE + pom + import + + + + + + org.springframework + spring-context + + + org.springframework + spring-web + + + diff --git a/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java b/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java new file mode 100644 index 0000000000..7c1e7f7c1d --- /dev/null +++ b/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.bom; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class HelloWorldApp { + + public static void main(String[] args) { + ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class); + HelloWorldBean helloWorldBean = ctx.getBean(HelloWorldBean.class); + System.out.println(helloWorldBean.sayHello()); + } + +} diff --git a/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java b/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java new file mode 100644 index 0000000000..f51b150f0a --- /dev/null +++ b/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java @@ -0,0 +1,8 @@ +package com.baeldung.spring.bom; + +public class HelloWorldBean { + + public String sayHello() { + return "Hello World With Maven BOM"; + } +} diff --git a/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java b/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java new file mode 100644 index 0000000000..8dc0e2c806 --- /dev/null +++ b/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.bom; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HelloWorldConfig { + + @Bean + public HelloWorldBean helloWorldBean() { + return new HelloWorldBean(); + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml index 3d8c40afdd..84dc2a6ca9 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml @@ -44,6 +44,10 @@ org.springframework.cloud spring-cloud-starter-zipkin + + org.springframework.cloud + spring-cloud-starter-feign + diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java index 16aae66cab..10ed66bfd4 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java @@ -1,5 +1,7 @@ package com.baeldung.spring.cloud.bootstrap.gateway; +import com.baeldung.spring.cloud.bootstrap.gateway.client.book.BooksClient; +import com.baeldung.spring.cloud.bootstrap.gateway.client.rating.RatingsClient; import com.netflix.appinfo.InstanceInfo; import com.netflix.discovery.EurekaClient; import org.springframework.beans.factory.annotation.Autowired; @@ -8,6 +10,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.cloud.netflix.ribbon.RibbonClientSpecification; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @@ -16,6 +19,8 @@ import org.springframework.cloud.sleuth.zipkin.HttpZipkinSpanReporter; import org.springframework.cloud.sleuth.zipkin.ZipkinProperties; import org.springframework.cloud.sleuth.zipkin.ZipkinSpanReporter; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; import org.springframework.web.client.RestTemplate; import zipkin.Span; @@ -25,6 +30,7 @@ import java.util.List; @SpringBootApplication @EnableZuulProxy @EnableEurekaClient +@EnableFeignClients public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/book/Book.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/book/Book.java new file mode 100644 index 0000000000..d6a4d9269b --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/book/Book.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.bootstrap.gateway.client.book; + +import com.baeldung.spring.cloud.bootstrap.gateway.client.rating.Rating; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Book { + private Long id; + private String author; + private String title; + private List ratings; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getRatings() { + return ratings; + } + + public void setRatings(List ratings) { + this.ratings = ratings; + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/book/BooksClient.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/book/BooksClient.java new file mode 100644 index 0000000000..67e8f882ad --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/book/BooksClient.java @@ -0,0 +1,10 @@ +package com.baeldung.spring.cloud.bootstrap.gateway.client.book; + +import org.springframework.cloud.netflix.feign.FeignClient; +import org.springframework.web.bind.annotation.*; + +@FeignClient(value = "book-service") +public interface BooksClient { + @GetMapping("/books/{bookId}") + Book getBookById(@PathVariable("bookId") Long bookId); +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/rating/Rating.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/rating/Rating.java new file mode 100644 index 0000000000..21f9db2d98 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/rating/Rating.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.cloud.bootstrap.gateway.client.rating; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Rating { + private Long id; + private Long bookId; + private int stars; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getBookId() { + return bookId; + } + + public void setBookId(Long bookId) { + this.bookId = bookId; + } + + public int getStars() { + return stars; + } + + public void setStars(int stars) { + this.stars = stars; + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/rating/RatingsClient.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/rating/RatingsClient.java new file mode 100644 index 0000000000..4e87374b66 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/client/rating/RatingsClient.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.bootstrap.gateway.client.rating; + +import org.springframework.cloud.netflix.feign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@FeignClient(value = "rating-service") +public interface RatingsClient { + @GetMapping("/ratings") + List getRatingsByBookId(@RequestParam("bookId") Long bookId, @RequestHeader("Cookie") String session); +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/controller/CombinedController.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/controller/CombinedController.java new file mode 100644 index 0000000000..f04991f81d --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/controller/CombinedController.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.bootstrap.gateway.controller; + +import com.baeldung.spring.cloud.bootstrap.gateway.client.book.Book; +import com.baeldung.spring.cloud.bootstrap.gateway.client.book.BooksClient; +import com.baeldung.spring.cloud.bootstrap.gateway.client.rating.Rating; +import com.baeldung.spring.cloud.bootstrap.gateway.client.rating.RatingsClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/combined") +public class CombinedController { + + private final BooksClient booksClient; + private final RatingsClient ratingsClient; + + @Autowired + public CombinedController(BooksClient booksClient, RatingsClient ratingsClient) { + this.booksClient = booksClient; + this.ratingsClient = ratingsClient; + } + + @GetMapping + public Book getCombinedResponse(@RequestParam Long bookId, @CookieValue("SESSION") String session){ + Book book = booksClient.getBookById(bookId); + List ratings = ratingsClient.getRatingsByBookId(bookId, "SESSION="+session); + book.setRatings(ratings); + return book; + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/LiveTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/LiveTest.java index 04ddc0ee7a..2bef67934b 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/LiveTest.java +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/LiveTest.java @@ -1,5 +1,7 @@ package com.baeldung.spring.cloud.bootstrap.gateway; +import com.baeldung.spring.cloud.bootstrap.gateway.client.book.Book; +import com.baeldung.spring.cloud.bootstrap.gateway.client.rating.Rating; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import io.restassured.RestAssured; import io.restassured.authentication.FormAuthConfig; @@ -80,7 +82,9 @@ public class LiveTest { @Test public void whenAddnewRating_thenSuccess() { - final Rating rating = new Rating(1L, 4); + final Rating rating = new Rating(); + rating.setBookId(1L); + rating.setStars(4); // request the protected resource final Response ratingResponse = RestAssured.given() @@ -98,7 +102,9 @@ public class LiveTest { @Test public void whenAddnewBook_thenSuccess() { - final Book book = new Book("Baeldung", "How to spring cloud"); + final Book book = new Book(); + book.setTitle("How to spring cloud"); + book.setAuthor("Baeldung"); // request the protected resource final Response bookResponse = RestAssured.given() @@ -115,83 +121,17 @@ public class LiveTest { } - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Book { - - private Long id; - private String author; - private String title; - - public Book() { - } - - public Book(String author, String title) { - this.author = author; - this.title = title; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } + @Test + public void accessCombinedEndpoint() { + final Response response = RestAssured.given() + .auth() + .form("user", "password", formConfig) + .get(ROOT_URI + "/combined?bookId=1"); + Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode()); + Assert.assertNotNull(response.getBody()); + final Book result = response.as(Book.class); + Assert.assertEquals(new Long(1), result.getId()); + Assert.assertNotNull(result.getRatings()); + Assert.assertTrue(result.getRatings().size() > 0); } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Rating { - private Long id; - private Long bookId; - private int stars; - - public Rating() { - } - - public Rating(Long bookId, int stars) { - this.bookId = bookId; - this.stars = stars; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getBookId() { - return bookId; - } - - public void setBookId(Long bookId) { - this.bookId = bookId; - } - - public int getStars() { - return stars; - } - - public void setStars(int stars) { - this.stars = stars; - } - } - } \ No newline at end of file diff --git a/spring-core/README.md b/spring-core/README.md index 3f2abe42a1..380b3138fe 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -5,3 +5,4 @@ - [Constructor Dependency Injection in Spring](http://www.baeldung.com/constructor-injection-in-spring) - [Constructor Injection in Spring with Lombok](http://www.baeldung.com/spring-injection-lombok) - [A Quick Guide to Spring @Value](http://www.baeldung.com/spring-value-annotation) +- [Spring YAML Configuration](http://www.baeldung.com/spring-yaml) diff --git a/spring-core/pom.xml b/spring-core/pom.xml index 70002bf3c1..85cf4573aa 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -58,12 +58,17 @@ lombok ${lombok.version} + + org.springframework.boot + spring-boot-starter + 1.5.2.RELEASE + org.springframework.boot spring-boot-test ${mockito.spring.boot.version} test - + diff --git a/spring-core/src/main/java/com/baeldung/yaml/MyApplication.java b/spring-core/src/main/java/com/baeldung/yaml/MyApplication.java new file mode 100644 index 0000000000..4a585df998 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/yaml/MyApplication.java @@ -0,0 +1,31 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.baeldung.yaml; + +import java.util.Collections; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MyApplication implements CommandLineRunner { + + @Autowired + private YAMLConfig myConfig; + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(MyApplication.class); + app.run(); + } + + public void run(String... args) throws Exception { + System.out.println("using environment:" + myConfig.getEnvironment()); + System.out.println("name:" + myConfig.getName()); + System.out.println("servers:" + myConfig.getServers()); + } + +} diff --git a/spring-core/src/main/java/com/baeldung/yaml/YAMLConfig.java b/spring-core/src/main/java/com/baeldung/yaml/YAMLConfig.java new file mode 100644 index 0000000000..313b920502 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/yaml/YAMLConfig.java @@ -0,0 +1,41 @@ +package com.baeldung.yaml; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties +@ConfigurationProperties +public class YAMLConfig { + private String name; + private String environment; + private List servers = new ArrayList(); + + public List getServers() { + return servers; + } + + public void setServers(List servers) { + this.servers = servers; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEnvironment() { + return environment; + } + + public void setEnvironment(String environment) { + this.environment = environment; + } + +} diff --git a/spring-core/src/main/resources/application.properties b/spring-core/src/main/resources/application.properties index fdc6536237..11710b49aa 100644 --- a/spring-core/src/main/resources/application.properties +++ b/spring-core/src/main/resources/application.properties @@ -1,2 +1,2 @@ -someInitialValue=This is only sample value -anotherValue=Another configured value \ No newline at end of file +spring.profiles.active=prod + diff --git a/spring-core/src/main/resources/application.yml b/spring-core/src/main/resources/application.yml new file mode 100644 index 0000000000..6fc6f67cd0 --- /dev/null +++ b/spring-core/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + profiles: test +name: test-YAML +environment: test +servers: + - www.abc.test.com + - www.xyz.test.com + +--- + +spring: + profiles: prod +name: prod-YAML +environment: production +servers: + - www.abc.com + - www.xyz.com diff --git a/spring-jooq/pom.xml b/spring-jooq/pom.xml index e6ae05eb0f..763465be8c 100644 --- a/spring-jooq/pom.xml +++ b/spring-jooq/pom.xml @@ -1,8 +1,7 @@ 4.0.0 - com.baeldung - sprin-jooq + spring-jooq 0.0.1-SNAPSHOT diff --git a/spring-mvc-java/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java b/spring-mvc-java/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java new file mode 100644 index 0000000000..539a6032a6 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java @@ -0,0 +1,27 @@ +package com.baeldung.exception; + +import org.springframework.http.MediaType; +import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.util.Map; + +@RestController +public class HttpMediaTypeNotAcceptableExceptionExampleController { + + @PostMapping(value = "/test", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public Map test() { + return Collections.singletonMap("key", "value"); + } + + @ResponseBody + @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) + public String handleHttpMediaTypeNotAcceptableException() { + return "acceptable MIME type:" + MediaType.APPLICATION_JSON_VALUE; + } + +} diff --git a/spring-mvc-java/src/test/java/com/baeldung/aop/AopPublishingIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/aop/AopPublishingIntegrationTest.java index cf9c83a93d..2503900e69 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/aop/AopPublishingIntegrationTest.java +++ b/spring-mvc-java/src/test/java/com/baeldung/aop/AopPublishingIntegrationTest.java @@ -22,7 +22,7 @@ import java.util.regex.Pattern; import static org.junit.Assert.assertTrue; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class) public class AopPublishingIntegrationTest { @Before diff --git a/spring-rest-simple/src/main/java/org/baeldung/config/WebConfig.java b/spring-rest-simple/src/main/java/org/baeldung/config/WebConfig.java index 4eb476411e..ec92ad8349 100644 --- a/spring-rest-simple/src/main/java/org/baeldung/config/WebConfig.java +++ b/spring-rest-simple/src/main/java/org/baeldung/config/WebConfig.java @@ -6,12 +6,16 @@ import java.util.List; import org.baeldung.config.converter.KryoHttpMessageConverter; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter; +import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; import org.springframework.oxm.xstream.XStreamMarshaller; +import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @@ -23,39 +27,42 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter @ComponentScan({ "org.baeldung.web" }) public class WebConfig extends WebMvcConfigurerAdapter { - public WebConfig() { - super(); - } + public WebConfig() { + super(); + } - // + // - @Override - public void configureMessageConverters( - final List> messageConverters) { - final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); - builder.indentOutput(true).dateFormat( - new SimpleDateFormat("dd-MM-yyyy hh:mm")); - messageConverters.add(new MappingJackson2HttpMessageConverter(builder - .build())); - // messageConverters.add(new - // MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); + @Override + public void configureMessageConverters(final List> messageConverters) { + final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); + builder.indentOutput(true) + .dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm")); + messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build())); + messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true) + .build())); - // messageConverters.add(createXmlHttpMessageConverter()); - // messageConverters.add(new MappingJackson2HttpMessageConverter()); + messageConverters.add(createXmlHttpMessageConverter()); + // messageConverters.add(new MappingJackson2HttpMessageConverter()); - messageConverters.add(new ProtobufHttpMessageConverter()); - messageConverters.add(new KryoHttpMessageConverter()); - super.configureMessageConverters(messageConverters); - } + messageConverters.add(new ProtobufHttpMessageConverter()); + messageConverters.add(new KryoHttpMessageConverter()); + messageConverters.add(new StringHttpMessageConverter()); + super.configureMessageConverters(messageConverters); + } - private HttpMessageConverter createXmlHttpMessageConverter() { - final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); + private HttpMessageConverter createXmlHttpMessageConverter() { + final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); - final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); - xmlConverter.setMarshaller(xstreamMarshaller); - xmlConverter.setUnmarshaller(xstreamMarshaller); + final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); + xmlConverter.setMarshaller(xstreamMarshaller); + xmlConverter.setUnmarshaller(xstreamMarshaller); - return xmlConverter; - } + return xmlConverter; + } + @Override + public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { + configurer.defaultContentType(MediaType.APPLICATION_JSON); + } } diff --git a/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java b/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java index 6d27ecece4..3c7e5ed13c 100644 --- a/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java +++ b/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java @@ -3,6 +3,7 @@ package org.baeldung.web.controller; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import org.baeldung.web.dto.Foo; +import org.baeldung.web.dto.FooProtos; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; @@ -15,25 +16,33 @@ import org.springframework.web.bind.annotation.ResponseStatus; @Controller public class FooController { - public FooController() { - super(); - } + public FooController() { + super(); + } - // API - read + // API - read - @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") - @ResponseBody - public Foo findById(@PathVariable final long id) { - return new Foo(id, randomAlphabetic(4)); - } + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") + @ResponseBody + public Foo findById(@PathVariable final long id) { + return new Foo(id, randomAlphabetic(4)); + } - // API - write + // API - write - @RequestMapping(method = RequestMethod.PUT, value = "/foos/{id}") - @ResponseStatus(HttpStatus.OK) - @ResponseBody - public Foo updateFoo(@PathVariable("id") final String id, - @RequestBody final Foo foo) { - return foo; - } + @RequestMapping(method = RequestMethod.PUT, value = "/foos/{id}") + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public Foo updateFoo(@PathVariable("id") final String id, @RequestBody final Foo foo) { + return foo; + } + + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}", produces = { "application/x-protobuf" }) + @ResponseBody + public FooProtos.Foo findProtoById(@PathVariable final long id) { + return FooProtos.Foo.newBuilder() + .setId(1) + .setName("Foo Name") + .build(); + } } diff --git a/spring-rest-simple/src/main/webapp/WEB-INF/api-servlet.xml b/spring-rest-simple/src/main/webapp/WEB-INF/api-servlet.xml deleted file mode 100644 index 0f80990c16..0000000000 --- a/spring-rest-simple/src/main/webapp/WEB-INF/api-servlet.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - /WEB-INF/spring-views.xml - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java b/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java index eaf55ee81b..40e93f2d89 100644 --- a/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java +++ b/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java @@ -1,17 +1,11 @@ package org.baeldung.client; -import static org.apache.commons.codec.binary.Base64.encodeBase64; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.io.IOException; -import java.net.URI; -import java.util.Arrays; -import java.util.Set; import org.baeldung.web.dto.Foo; import org.junit.Before; @@ -22,21 +16,13 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RequestCallback; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Charsets; - public class RestTemplateBasicLiveTest { private RestTemplate restTemplate; - private static final String fooResourceUrl = String.format("http://localhost:%d/spring-rest/myfoos", 8082); + private static final String fooResourceUrl = String.format("http://localhost:%d/spring-rest/foos", 8082); @Before public void beforeTest() { @@ -52,16 +38,6 @@ public class RestTemplateBasicLiveTest { assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); } - @Test - public void givenResourceUrl_whenSendGetForRequestEntity_thenBodyCorrect() throws IOException { - final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); - - final ObjectMapper mapper = new ObjectMapper(); - final JsonNode root = mapper.readTree(response.getBody()); - final JsonNode name = root.path("name"); - assertThat(name.asText(), notNullValue()); - } - @Test public void givenResourceUrl_whenRetrievingResource_thenCorrect() throws IOException { final Foo foo = restTemplate.getForObject(fooResourceUrl + "/1", Foo.class); @@ -70,147 +46,19 @@ public class RestTemplateBasicLiveTest { assertThat(foo.getId(), is(1L)); } - // HEAD, OPTIONS - - @Test - public void givenFooService_whenCallHeadForHeaders_thenReceiveAllHeadersForThatResource() { - final HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl); - - assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON)); - } - - // POST - - @Test - public void givenFooService_whenPostForObject_thenCreatedObjectIsReturned() { - final HttpEntity request = new HttpEntity<>(new Foo("bar")); - final Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class); - assertThat(foo, notNullValue()); - assertThat(foo.getName(), is("bar")); - } - - @Test - public void givenFooService_whenPostForLocation_thenCreatedLocationIsReturned() { - final HttpEntity request = new HttpEntity<>(new Foo("bar")); - final URI location = restTemplate.postForLocation(fooResourceUrl, request); - assertThat(location, notNullValue()); - } - - @Test - public void givenFooService_whenPostResource_thenResourceIsCreated() { - final RestTemplate template = new RestTemplate(); - - final HttpEntity request = new HttpEntity<>(new Foo("bar")); - - final ResponseEntity response = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); - final Foo foo = response.getBody(); - assertThat(foo, notNullValue()); - assertThat(foo.getName(), is("bar")); - } - - @Test - public void givenFooService_whenCallOptionsForAllow_thenReceiveValueOfAllowHeader() { - final Set optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl); - final HttpMethod[] supportedMethods = { HttpMethod.GET, HttpMethod.POST, HttpMethod.HEAD }; - - assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods))); - } - // PUT @Test - public void givenFooService_whenPutExistingEntity_thenItIsUpdated() { - final RestTemplate template = new RestTemplate(); - final HttpHeaders headers = prepareBasicAuthHeaders(); - final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); - - // Create Resource - final ResponseEntity createResponse = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); - - // Update Resource - final Foo updatedInstance = new Foo("newName"); - updatedInstance.setId(createResponse.getBody().getId()); - final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId(); - final HttpEntity requestUpdate = new HttpEntity<>(updatedInstance, headers); - template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class); - - // Check that Resource was updated - final ResponseEntity updateResponse = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); - final Foo foo = updateResponse.getBody(); - assertThat(foo.getName(), is(updatedInstance.getName())); - } - - @Test - public void givenFooService_whenPutExistingEntityWithCallback_thenItIsUpdated() { - final RestTemplate template = new RestTemplate(); - final HttpHeaders headers = prepareBasicAuthHeaders(); - final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); - - // Create entity - ResponseEntity response = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); - - // Update entity - final Foo updatedInstance = new Foo("newName"); - updatedInstance.setId(response.getBody().getId()); - final String resourceUrl = fooResourceUrl + '/' + response.getBody().getId(); - template.execute(resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null); - - // Check that entity was updated - response = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); - final Foo foo = response.getBody(); - assertThat(foo.getName(), is(updatedInstance.getName())); - } - - // DELETE - - @Test - public void givenFooService_whenCallDelete_thenEntityIsRemoved() { - final Foo foo = new Foo("remove me"); - final ResponseEntity response = restTemplate.postForEntity(fooResourceUrl, foo, Foo.class); - assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); - - final String entityUrl = fooResourceUrl + "/" + response.getBody().getId(); - restTemplate.delete(entityUrl); - try { - restTemplate.getForEntity(entityUrl, Foo.class); - fail(); - } catch (final HttpClientErrorException ex) { - assertThat(ex.getStatusCode(), is(HttpStatus.NOT_FOUND)); - } - } - - // - - private HttpHeaders prepareBasicAuthHeaders() { + public void givenFooService_whenPutObject_thenUpdatedObjectIsReturned() { final HttpHeaders headers = new HttpHeaders(); - final String encodedLogPass = getBase64EncodedLogPass(); - headers.add(HttpHeaders.AUTHORIZATION, "Basic " + encodedLogPass); - return headers; + headers.setContentType(MediaType.APPLICATION_JSON); + final Foo foo = new Foo(1, "newName"); + final String resourceUrl = fooResourceUrl + "/1"; + final HttpEntity requestUpdate = new HttpEntity<>(foo, headers); + final ResponseEntity response = restTemplate.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Foo.class); + + assertThat(foo.getName(), is(response.getBody() + .getName())); } - private String getBase64EncodedLogPass() { - final String logPass = "user1:user1Pass"; - final byte[] authHeaderBytes = encodeBase64(logPass.getBytes(Charsets.US_ASCII)); - return new String(authHeaderBytes, Charsets.US_ASCII); - } - - private RequestCallback requestCallback(final Foo updatedInstance) { - return clientHttpRequest -> { - final ObjectMapper mapper = new ObjectMapper(); - mapper.writeValue(clientHttpRequest.getBody(), updatedInstance); - clientHttpRequest.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - clientHttpRequest.getHeaders().add(HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); - }; - } - - // Simply setting restTemplate timeout using ClientHttpRequestFactory - - ClientHttpRequestFactory getSimpleClientHttpRequestFactory() { - final int timeout = 5; - final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); - clientHttpRequestFactory.setConnectTimeout(timeout * 1000); - return clientHttpRequestFactory; - } } diff --git a/spring-rest-simple/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-rest-simple/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java index 18fc73d1b4..012221efb7 100644 --- a/spring-rest-simple/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java +++ b/spring-rest-simple/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java @@ -20,7 +20,7 @@ public class TestRestTemplateBasicLiveTest { private RestTemplate restTemplate; - private static final String FOO_RESOURCE_URL = "http://localhost:" + 8082 + "/spring-rest/myfoos"; + private static final String FOO_RESOURCE_URL = "http://localhost:" + 8082 + "/spring-rest/foos"; private static final String URL_SECURED_BY_AUTHENTICATION = "http://httpbin.org/basic-auth/user/passwd"; private static final String BASE_URL = "http://localhost:" + 8082 + "/spring-rest"; diff --git a/spring-rest/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java b/spring-rest-simple/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java similarity index 100% rename from spring-rest/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java rename to spring-rest-simple/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java diff --git a/spring-rest-simple/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java b/spring-rest-simple/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java index bf0bbc67dc..9dd6b13f18 100644 --- a/spring-rest-simple/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java +++ b/spring-rest-simple/src/test/java/org/baeldung/web/test/RequestMappingLiveTest.java @@ -3,61 +3,118 @@ package org.baeldung.web.test; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; -import com.jayway.restassured.RestAssured; import org.junit.Test; +import com.jayway.restassured.RestAssured; public class RequestMappingLiveTest { private static String BASE_URI = "http://localhost:8082/spring-rest/ex/"; @Test public void givenSimplePath_whenGetFoos_thenOk() { - RestAssured.given().accept("text/html").get(BASE_URI + "foos").then().assertThat().body(equalTo("Simple Get some Foos")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "foos") + .then() + .assertThat() + .body(equalTo("Simple Get some Foos")); } @Test public void whenPostFoos_thenOk() { - RestAssured.given().accept("text/html").post(BASE_URI + "foos").then().assertThat().body(equalTo("Post some Foos")); + RestAssured.given() + .accept("text/html") + .post(BASE_URI + "foos") + .then() + .assertThat() + .body(equalTo("Post some Foos")); } @Test public void givenOneHeader_whenGetFoos_thenOk() { - RestAssured.given().accept("text/html").header("key", "val").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header")); + RestAssured.given() + .accept("text/html") + .header("key", "val") + .get(BASE_URI + "foos") + .then() + .assertThat() + .body(equalTo("Get some Foos with Header")); } @Test public void givenMultipleHeaders_whenGetFoos_thenOk() { - RestAssured.given().accept("text/html").headers("key1", "val1", "key2", "val2").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header")); + RestAssured.given() + .accept("text/html") + .headers("key1", "val1", "key2", "val2") + .get(BASE_URI + "foos") + .then() + .assertThat() + .body(equalTo("Get some Foos with Header")); } @Test public void givenAcceptHeader_whenGetFoos_thenOk() { - RestAssured.given().accept("application/json").get(BASE_URI + "foos").then().assertThat().body(containsString("Get some Foos with Header New")); + RestAssured.given() + .accept("application/json") + .get(BASE_URI + "foos") + .then() + .assertThat() + .body(containsString("Get some Foos with Header New")); } @Test public void givenPathVariable_whenGetFoos_thenOk() { - RestAssured.given().accept("text/html").get(BASE_URI + "foos/1").then().assertThat().body(equalTo("Get a specific Foo with id=1")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "foos/1") + .then() + .assertThat() + .body(equalTo("Get a specific Foo with id=1")); } @Test public void givenMultiplePathVariable_whenGetFoos_thenOk() { - RestAssured.given().accept("text/html").get(BASE_URI + "foos/1/bar/2").then().assertThat().body(equalTo("Get a specific Bar with id=2 from a Foo with id=1")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "foos/1/bar/2") + .then() + .assertThat() + .body(equalTo("Get a specific Bar with id=2 from a Foo with id=1")); } @Test public void givenPathVariable_whenGetBars_thenOk() { - RestAssured.given().accept("text/html").get(BASE_URI + "bars/1").then().assertThat().body(equalTo("Get a specific Bar with id=1")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "bars/1") + .then() + .assertThat() + .body(equalTo("Get a specific Bar with id=1")); } @Test public void givenParams_whenGetBars_thenOk() { - RestAssured.given().accept("text/html").get(BASE_URI + "bars?id=100&second=something").then().assertThat().body(equalTo("Get a specific Bar with id=100")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "bars?id=100&second=something") + .then() + .assertThat() + .body(equalTo("Get a specific Bar with id=100")); } @Test public void whenGetFoosOrBars_thenOk() { - RestAssured.given().accept("text/html").get(BASE_URI + "advanced/foos").then().assertThat().body(equalTo("Advanced - Get some Foos or Bars")); - RestAssured.given().accept("text/html").get(BASE_URI + "advanced/bars").then().assertThat().body(equalTo("Advanced - Get some Foos or Bars")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "advanced/foos") + .then() + .assertThat() + .body(equalTo("Advanced - Get some Foos or Bars")); + RestAssured.given() + .accept("text/html") + .get(BASE_URI + "advanced/bars") + .then() + .assertThat() + .body(equalTo("Advanced - Get some Foos or Bars")); } } diff --git a/spring-rest/src/main/java/com/baeldung/produceimage/Application.java b/spring-rest/src/main/java/com/baeldung/produceimage/ImageApplication.java similarity index 70% rename from spring-rest/src/main/java/com/baeldung/produceimage/Application.java rename to spring-rest/src/main/java/com/baeldung/produceimage/ImageApplication.java index 179671d094..82a6203fe5 100644 --- a/spring-rest/src/main/java/com/baeldung/produceimage/Application.java +++ b/spring-rest/src/main/java/com/baeldung/produceimage/ImageApplication.java @@ -3,12 +3,11 @@ package com.baeldung.produceimage; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.PropertySource; @EnableAutoConfiguration @ComponentScan("com.baeldung.produceimage") -public class Application { +public class ImageApplication { public static void main(final String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run(ImageApplication.class, args); } } diff --git a/spring-rest/src/main/java/org/baeldung/config/Application.java b/spring-rest/src/main/java/org/baeldung/config/MainApplication.java similarity index 76% rename from spring-rest/src/main/java/org/baeldung/config/Application.java rename to spring-rest/src/main/java/org/baeldung/config/MainApplication.java index 077213b04d..e31fdfaaa9 100644 --- a/spring-rest/src/main/java/org/baeldung/config/Application.java +++ b/spring-rest/src/main/java/org/baeldung/config/MainApplication.java @@ -7,10 +7,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter @EnableAutoConfiguration @ComponentScan("org.baeldung") -public class Application extends WebMvcConfigurerAdapter { +public class MainApplication extends WebMvcConfigurerAdapter { public static void main(final String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run(MainApplication.class, args); } } \ No newline at end of file diff --git a/spring-rest/src/main/java/org/baeldung/config/WebConfig.java b/spring-rest/src/main/java/org/baeldung/config/WebConfig.java index a019a5a9bb..3661b2c561 100644 --- a/spring-rest/src/main/java/org/baeldung/config/WebConfig.java +++ b/spring-rest/src/main/java/org/baeldung/config/WebConfig.java @@ -1,19 +1,18 @@ package org.baeldung.config; +import java.text.SimpleDateFormat; +import java.util.List; + import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter; import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; import org.springframework.oxm.xstream.XStreamMarshaller; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import java.text.SimpleDateFormat; -import java.util.List; - /* * Please note that main web configuration is in src/main/webapp/WEB-INF/api-servlet.xml */ @@ -31,14 +30,15 @@ public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(final List> messageConverters) { final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); - builder.indentOutput(true).dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm")); + builder.indentOutput(true) + .dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm")); messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build())); // messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); // messageConverters.add(createXmlHttpMessageConverter()); // messageConverters.add(new MappingJackson2HttpMessageConverter()); - messageConverters.add(new ProtobufHttpMessageConverter()); + // messageConverters.add(new ProtobufHttpMessageConverter()); super.configureMessageConverters(messageConverters); } diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java b/spring-rest/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java new file mode 100644 index 0000000000..1c3a1086ca --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/BarMappingExamplesController.java @@ -0,0 +1,47 @@ +package org.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/ex") +public class BarMappingExamplesController { + + public BarMappingExamplesController() { + super(); + } + + // API + + // with @RequestParam + + @RequestMapping(value = "/bars") + @ResponseBody + public String getBarBySimplePathWithRequestParam(@RequestParam("id") final long id) { + return "Get a specific Bar with id=" + id; + } + + @RequestMapping(value = "/bars", params = "id") + @ResponseBody + public String getBarBySimplePathWithExplicitRequestParam(@RequestParam("id") final long id) { + return "Get a specific Bar with id=" + id; + } + + @RequestMapping(value = "/bars", params = { "id", "second" }) + @ResponseBody + public String getBarBySimplePathWithExplicitRequestParams(@RequestParam("id") final long id) { + return "Get a specific Bar with id=" + id; + } + + // with @PathVariable + + @RequestMapping(value = "/bars/{numericId:[\\d]+}") + @ResponseBody + public String getBarsBySimplePathWithPathVariable(@PathVariable final long numericId) { + return "Get a specific Bar with id=" + numericId; + } + +} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/MyFooController.java b/spring-rest/src/main/java/org/baeldung/web/controller/MyFooController.java index f19ddca435..061213a3e9 100644 --- a/spring-rest/src/main/java/org/baeldung/web/controller/MyFooController.java +++ b/spring-rest/src/main/java/org/baeldung/web/controller/MyFooController.java @@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @Controller -@RequestMapping(value = "/myfoos") +@RequestMapping(value = "/foos") public class MyFooController { private final Map myfoos; @@ -58,12 +58,20 @@ public class MyFooController { return foo; } + @RequestMapping(method = RequestMethod.PATCH, value = "/{id}") + @ResponseStatus(HttpStatus.OK) + public void updateFoo2(@PathVariable("id") final long id, @RequestBody final Foo foo) { + myfoos.put(id, foo); + } + @RequestMapping(method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public Foo createFoo(@RequestBody final Foo foo, HttpServletResponse response) { myfoos.put(foo.getId(), foo); - response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentRequest().path("/" + foo.getId()).toUriString()); + response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentRequest() + .path("/" + foo.getId()) + .toUriString()); return foo; } diff --git a/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml b/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml index 0f80990c16..d133bcea22 100644 --- a/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml +++ b/spring-rest/src/main/webapp/WEB-INF/api-servlet.xml @@ -19,9 +19,8 @@ --> - - - + diff --git a/spring-rest/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java b/spring-rest/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java index c9dad8ccf0..2d12262e85 100644 --- a/spring-rest/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java @@ -25,6 +25,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RequestCallback; import org.springframework.web.client.RestTemplate; @@ -36,25 +37,27 @@ import com.google.common.base.Charsets; public class RestTemplateBasicLiveTest { private RestTemplate restTemplate; - private static final String fooResourceUrl = "http://localhost:" + APPLICATION_PORT + "/spring-rest/myfoos"; + private static final String fooResourceUrl = "http://localhost:" + APPLICATION_PORT + "/spring-rest/foos"; @Before public void beforeTest() { restTemplate = new RestTemplate(); + restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter())); } // GET @Test public void givenResourceUrl_whenSendGetForRequestEntity_thenStatusOk() throws IOException { - final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); + final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", Foo.class); assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); } @Test public void givenResourceUrl_whenSendGetForRequestEntity_thenBodyCorrect() throws IOException { - final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); + final RestTemplate template = new RestTemplate(); + final ResponseEntity response = template.getForEntity(fooResourceUrl + "/1", String.class); final ObjectMapper mapper = new ObjectMapper(); final JsonNode root = mapper.readTree(response.getBody()); @@ -76,7 +79,8 @@ public class RestTemplateBasicLiveTest { public void givenFooService_whenCallHeadForHeaders_thenReceiveAllHeadersForThatResource() { final HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl); - assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON)); + assertTrue(httpHeaders.getContentType() + .includes(MediaType.APPLICATION_JSON)); } // POST @@ -98,15 +102,13 @@ public class RestTemplateBasicLiveTest { @Test public void givenFooService_whenPostResource_thenResourceIsCreated() { - final RestTemplate template = new RestTemplate(); + final Foo foo = new Foo("bar"); + final ResponseEntity response = restTemplate.postForEntity(fooResourceUrl, foo, Foo.class); - final HttpEntity request = new HttpEntity<>(new Foo("bar")); - - final ResponseEntity response = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); - final Foo foo = response.getBody(); - assertThat(foo, notNullValue()); - assertThat(foo.getName(), is("bar")); + final Foo fooResponse = response.getBody(); + assertThat(fooResponse, notNullValue()); + assertThat(fooResponse.getName(), is("bar")); } @Test @@ -121,44 +123,46 @@ public class RestTemplateBasicLiveTest { @Test public void givenFooService_whenPutExistingEntity_thenItIsUpdated() { - final RestTemplate template = new RestTemplate(); final HttpHeaders headers = prepareBasicAuthHeaders(); final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); // Create Resource - final ResponseEntity createResponse = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); + final ResponseEntity createResponse = restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); // Update Resource final Foo updatedInstance = new Foo("newName"); - updatedInstance.setId(createResponse.getBody().getId()); - final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId(); + updatedInstance.setId(createResponse.getBody() + .getId()); + final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody() + .getId(); final HttpEntity requestUpdate = new HttpEntity<>(updatedInstance, headers); - template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class); + restTemplate.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class); // Check that Resource was updated - final ResponseEntity updateResponse = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); + final ResponseEntity updateResponse = restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); final Foo foo = updateResponse.getBody(); assertThat(foo.getName(), is(updatedInstance.getName())); } @Test public void givenFooService_whenPutExistingEntityWithCallback_thenItIsUpdated() { - final RestTemplate template = new RestTemplate(); final HttpHeaders headers = prepareBasicAuthHeaders(); final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); // Create entity - ResponseEntity response = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); + ResponseEntity response = restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); // Update entity final Foo updatedInstance = new Foo("newName"); - updatedInstance.setId(response.getBody().getId()); - final String resourceUrl = fooResourceUrl + '/' + response.getBody().getId(); - template.execute(resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null); + updatedInstance.setId(response.getBody() + .getId()); + final String resourceUrl = fooResourceUrl + '/' + response.getBody() + .getId(); + restTemplate.execute(resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null); // Check that entity was updated - response = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); + response = restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); final Foo foo = response.getBody(); assertThat(foo.getName(), is(updatedInstance.getName())); } @@ -167,22 +171,26 @@ public class RestTemplateBasicLiveTest { @Test public void givenFooService_whenPatchExistingEntity_thenItIsUpdated() { - final RestTemplate template = new RestTemplate(); final HttpHeaders headers = prepareBasicAuthHeaders(); final HttpEntity request = new HttpEntity<>(new Foo("bar"), headers); // Create Resource - final ResponseEntity createResponse = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); + final ResponseEntity createResponse = restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); // Update Resource final Foo updatedResource = new Foo("newName"); - updatedResource.setId(createResponse.getBody().getId()); - final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId(); + updatedResource.setId(createResponse.getBody() + .getId()); + final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody() + .getId(); final HttpEntity requestUpdate = new HttpEntity<>(updatedResource, headers); + final ClientHttpRequestFactory requestFactory = getSimpleClientHttpRequestFactory(); + final RestTemplate template = new RestTemplate(requestFactory); + template.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter())); template.patchForObject(resourceUrl, requestUpdate, Void.class); // Check that Resource was updated - final ResponseEntity updateResponse = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); + final ResponseEntity updateResponse = restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class); final Foo foo = updateResponse.getBody(); assertThat(foo.getName(), is(updatedResource.getName())); } @@ -195,7 +203,8 @@ public class RestTemplateBasicLiveTest { final ResponseEntity response = restTemplate.postForEntity(fooResourceUrl, foo, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); - final String entityUrl = fooResourceUrl + "/" + response.getBody().getId(); + final String entityUrl = fooResourceUrl + "/" + response.getBody() + .getId(); restTemplate.delete(entityUrl); try { restTemplate.getForEntity(entityUrl, Foo.class); @@ -224,8 +233,10 @@ public class RestTemplateBasicLiveTest { return clientHttpRequest -> { final ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(clientHttpRequest.getBody(), updatedInstance); - clientHttpRequest.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - clientHttpRequest.getHeaders().add(HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); + clientHttpRequest.getHeaders() + .add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + clientHttpRequest.getHeaders() + .add(HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); }; } diff --git a/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java index a4d8eb0908..a26801429e 100644 --- a/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertTrue; public class TestRestTemplateBasicLiveTest { private RestTemplate restTemplate; - private static final String FOO_RESOURCE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest/myfoos"; + private static final String FOO_RESOURCE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest/foos"; private static final String URL_SECURED_BY_AUTHENTICATION = "http://httpbin.org/basic-auth/user/passwd"; private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest"; diff --git a/spring-rest/src/test/resources/cache/2d9345a30d2cc31bb3091d70a8ef6c18.0 b/spring-rest/src/test/resources/cache/2d9345a30d2cc31bb3091d70a8ef6c18.0 index 78d5d3fcf3..f0a4a9d3fd 100644 --- a/spring-rest/src/test/resources/cache/2d9345a30d2cc31bb3091d70a8ef6c18.0 +++ b/spring-rest/src/test/resources/cache/2d9345a30d2cc31bb3091d70a8ef6c18.0 @@ -3,14 +3,14 @@ GET 0 HTTP/1.1 200 OK 10 -Server: nginx/1.10.0 (Ubuntu) -Date: Thu, 09 Mar 2017 10:17:25 GMT Content-Type: text/plain Content-Length: 1759 -Last-Modified: Tue, 27 May 2014 02:35:47 GMT Connection: keep-alive -ETag: "5383fa03-6df" Accept-Ranges: bytes +Server: nginx/1.10.0 (Ubuntu) +Date: Fri, 23 Jun 2017 15:44:52 GMT +Last-Modified: Tue, 27 May 2014 02:35:47 GMT +ETag: "5383fa03-6df" OkHttp-Sent-Millis: 1489054646765 OkHttp-Received-Millis: 1489054646966 diff --git a/spring-rest/src/test/resources/cache/4b217e04ba52215f3a6b64d28f6729c6.0 b/spring-rest/src/test/resources/cache/4b217e04ba52215f3a6b64d28f6729c6.0 index 82c93f0a86..c202030c3f 100644 --- a/spring-rest/src/test/resources/cache/4b217e04ba52215f3a6b64d28f6729c6.0 +++ b/spring-rest/src/test/resources/cache/4b217e04ba52215f3a6b64d28f6729c6.0 @@ -4,10 +4,10 @@ GET HTTP/1.1 301 Moved Permanently 8 Server: nginx/1.10.0 (Ubuntu) -Date: Thu, 09 Mar 2017 10:17:25 GMT +Date: Sat, 24 Jun 2017 01:06:43 GMT Content-Type: text/html Content-Length: 194 Connection: keep-alive Location: https://publicobject.com/helloworld.txt -OkHttp-Sent-Millis: 1489054646977 -OkHttp-Received-Millis: 1489054647185 +OkHttp-Sent-Millis: 1498266403462 +OkHttp-Received-Millis: 1498266403727 diff --git a/spring-rest/src/test/resources/cache/journal b/spring-rest/src/test/resources/cache/journal index 44b709c179..4640ee324c 100644 --- a/spring-rest/src/test/resources/cache/journal +++ b/spring-rest/src/test/resources/cache/journal @@ -10,3 +10,54 @@ CLEAN 2d9345a30d2cc31bb3091d70a8ef6c18 7618 1759 READ 4b217e04ba52215f3a6b64d28f6729c6 DIRTY 4b217e04ba52215f3a6b64d28f6729c6 CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +DIRTY 2d9345a30d2cc31bb3091d70a8ef6c18 +CLEAN 2d9345a30d2cc31bb3091d70a8ef6c18 7618 1759 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 +READ 2d9345a30d2cc31bb3091d70a8ef6c18 +READ 4b217e04ba52215f3a6b64d28f6729c6 +DIRTY 4b217e04ba52215f3a6b64d28f6729c6 +CLEAN 4b217e04ba52215f3a6b64d28f6729c6 333 194 diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/LiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java similarity index 98% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/LiveTest.java rename to spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java index dc5c265ed8..a8d273664d 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/web/LiveTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java @@ -12,7 +12,7 @@ import io.restassured.authentication.FormAuthConfig; import io.restassured.response.Response; import io.restassured.specification.RequestSpecification; -public class LiveTest { +public class ApplicationLiveTest { private final FormAuthConfig formAuthConfig = new FormAuthConfig("http://localhost:8082/spring-security-mvc-boot/login", "username", "password"); diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java index 3dd4b236f9..503354256f 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java @@ -21,22 +21,22 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.boot.test.context.SpringBootTest; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = { MvcConfig.class, SecurityConfig.class, PersistenceConfig.class }) +@SpringBootTest(classes = {MvcConfig.class, SecurityConfig.class, PersistenceConfig.class}) @WebAppConfiguration public class CustomUserDetailsServiceIntegrationTest { - public static final String USERNAME = "user"; - public static final String PASSWORD = "pass"; - public static final String USERNAME2 = "user2"; + private static final String USERNAME = "user"; + private static final String PASSWORD = "pass"; + private static final String USERNAME2 = "user2"; @Autowired - UserRepository myUserRepository; + private UserRepository myUserRepository; @Autowired - AuthenticationProvider authenticationProvider; + private AuthenticationProvider authenticationProvider; @Autowired - PasswordEncoder passwordEncoder; + private PasswordEncoder passwordEncoder; // diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java new file mode 100644 index 0000000000..9ef09f1f67 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java @@ -0,0 +1,61 @@ +package org.baeldung.web; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; + +import org.baeldung.multipleauthproviders.MultipleAuthProvidersApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MultipleAuthProvidersApplication.class) +public class MultipleAuthProvidersApplicationIntegrationTest { + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void givenMemUsers_whenGetPingWithValidUser_thenOk() { + ResponseEntity result = makeRestCallToGetPing("memuser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { + ResponseEntity result = makeRestCallToGetPing("externaluser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenAuthProviders_whenGetPingWithNoCred_then401() { + ResponseEntity result = makeRestCallToGetPing(); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + @Test + public void givenAuthProviders_whenGetPingWithBadCred_then401() { + ResponseEntity result = makeRestCallToGetPing("user", "bad_password"); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + private ResponseEntity makeRestCallToGetPing(String username, String password) { + return restTemplate.withBasicAuth(username, password) + .getForEntity("/api/ping", String.class, Collections.emptyMap()); + } + + private ResponseEntity makeRestCallToGetPing() { + return restTemplate.getForEntity("/api/ping", String.class, Collections.emptyMap()); + } +} diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java index 737b716209..157480c3f1 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java @@ -21,6 +21,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock @WebAppConfiguration @SpringBootTest(classes = MultipleEntryPointsApplication.class) public class MultipleEntryPointsIntegrationTest { + @Autowired private WebApplicationContext wac; diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java index 9de203b7c3..a568c22eec 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java @@ -14,7 +14,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private AuthenticationManager authenticationManager; @Override - protected void configure(HttpSecurity http) throws Exception { + protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.requestMatchers() .antMatchers("/login", "/oauth/authorize") .and() @@ -24,15 +24,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .and() .formLogin() .permitAll(); - } + } // @formatter:on @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.parentAuthenticationManager(authenticationManager) .inMemoryAuthentication() .withUser("john") .password("123") .roles("USER"); - } + } // @formatter:on } diff --git a/spring-vertx/src/main/java/com/baeldung/vertxspring/repository/ArticleRepository.java b/spring-vertx/src/main/java/com/baeldung/vertxspring/repository/ArticleRepository.java index 843c88b694..21f1ab7425 100644 --- a/spring-vertx/src/main/java/com/baeldung/vertxspring/repository/ArticleRepository.java +++ b/spring-vertx/src/main/java/com/baeldung/vertxspring/repository/ArticleRepository.java @@ -1,11 +1,7 @@ package com.baeldung.vertxspring.repository; -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - import com.baeldung.vertxspring.entity.Article; +import org.springframework.data.jpa.repository.JpaRepository; -@Repository -public interface ArticleRepository extends CrudRepository { - +public interface ArticleRepository extends JpaRepository { } diff --git a/spring-vertx/src/main/java/com/baeldung/vertxspring/service/ArticleService.java b/spring-vertx/src/main/java/com/baeldung/vertxspring/service/ArticleService.java index 55cb8bbfcb..8817701036 100644 --- a/spring-vertx/src/main/java/com/baeldung/vertxspring/service/ArticleService.java +++ b/spring-vertx/src/main/java/com/baeldung/vertxspring/service/ArticleService.java @@ -1,25 +1,20 @@ package com.baeldung.vertxspring.service; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import com.baeldung.vertxspring.entity.Article; import com.baeldung.vertxspring.repository.ArticleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; @Service public class ArticleService { @Autowired - ArticleRepository articleRepository; + private ArticleRepository articleRepository; public List
getAllArticle() { - List
articles = new ArrayList<>(); - articleRepository.findAll() - .forEach(articles::add); - return articles; + return articleRepository.findAll(); } }