Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -0,0 +1,104 @@
|
|||||||
|
package com.baeldung.algorithms.sudoku;
|
||||||
|
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class BacktrackingAlgorithm {
|
||||||
|
|
||||||
|
private static final int BOARD_SIZE = 9;
|
||||||
|
private static final int SUBSECTION_SIZE = 3;
|
||||||
|
private static final int BOARD_START_INDEX = 0;
|
||||||
|
|
||||||
|
private static final int NO_VALUE = 0;
|
||||||
|
private static final int MIN_VALUE = 1;
|
||||||
|
private static final int MAX_VALUE = 9;
|
||||||
|
|
||||||
|
private static int[][] board = {
|
||||||
|
{8, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 3, 6, 0, 0, 0, 0, 0},
|
||||||
|
{0, 7, 0, 0, 9, 0, 2, 0, 0},
|
||||||
|
{0, 5, 0, 0, 0, 7, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 4, 5, 7, 0, 0},
|
||||||
|
{0, 0, 0, 1, 0, 0, 0, 3, 0},
|
||||||
|
{0, 0, 1, 0, 0, 0, 0, 6, 8},
|
||||||
|
{0, 0, 8, 5, 0, 0, 0, 1, 0},
|
||||||
|
{0, 9, 0, 0, 0, 0, 4, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
BacktrackingAlgorithm solver = new BacktrackingAlgorithm();
|
||||||
|
solver.solve(board);
|
||||||
|
solver.printBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printBoard() {
|
||||||
|
for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
|
||||||
|
for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) {
|
||||||
|
System.out.print(board[row][column] + " ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean solve(int[][] board) {
|
||||||
|
for (int r = BOARD_START_INDEX; r < BOARD_SIZE; r++) {
|
||||||
|
for (int c = BOARD_START_INDEX; c < BOARD_SIZE; c++) {
|
||||||
|
if (board[r][c] == NO_VALUE) {
|
||||||
|
for (int k = MIN_VALUE; k <= MAX_VALUE; k++) {
|
||||||
|
board[r][c] = k;
|
||||||
|
if (isValid(board, r, c) && solve(board)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
board[r][c] = NO_VALUE;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValid(int[][] board, int r, int c) {
|
||||||
|
return rowConstraint(board, r) &&
|
||||||
|
columnConstraint(board, c) &&
|
||||||
|
subsectionConstraint(board, r, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean subsectionConstraint(int[][] board, int r, int c) {
|
||||||
|
boolean[] constraint = new boolean[BOARD_SIZE];
|
||||||
|
int subsectionRowStart = (r / SUBSECTION_SIZE) * SUBSECTION_SIZE;
|
||||||
|
int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE;
|
||||||
|
|
||||||
|
int subsectionColumnStart = (c / SUBSECTION_SIZE) * SUBSECTION_SIZE;
|
||||||
|
int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE;
|
||||||
|
|
||||||
|
for (int i = subsectionRowStart; i < subsectionRowEnd; i++) {
|
||||||
|
for (int j = subsectionColumnStart; j < subsectionColumnEnd; j++) {
|
||||||
|
if (!checkConstraint(board, i, constraint, j)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean columnConstraint(int[][] board, int c) {
|
||||||
|
boolean[] constraint = new boolean[BOARD_SIZE];
|
||||||
|
return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
|
||||||
|
.allMatch(i -> checkConstraint(board, i, constraint, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean rowConstraint(int[][] board, int r) {
|
||||||
|
boolean[] constraint = new boolean[BOARD_SIZE];
|
||||||
|
return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
|
||||||
|
.allMatch(i -> checkConstraint(board, r, constraint, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkConstraint(int[][] board, int r, boolean[] constraint, int c) {
|
||||||
|
if (board[r][c] != NO_VALUE) {
|
||||||
|
if (!constraint[board[r][c] - 1]) {
|
||||||
|
constraint[board[r][c] - 1] = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.algorithms.sudoku;
|
||||||
|
|
||||||
|
class ColumnNode extends DancingNode {
|
||||||
|
int size;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
ColumnNode(String n) {
|
||||||
|
super();
|
||||||
|
size = 0;
|
||||||
|
name = n;
|
||||||
|
C = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cover() {
|
||||||
|
unlinkLR();
|
||||||
|
for (DancingNode i = this.D; i != this; i = i.D) {
|
||||||
|
for (DancingNode j = i.R; j != i; j = j.R) {
|
||||||
|
j.unlinkUD();
|
||||||
|
j.C.size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uncover() {
|
||||||
|
for (DancingNode i = this.U; i != this; i = i.U) {
|
||||||
|
for (DancingNode j = i.L; j != i; j = j.L) {
|
||||||
|
j.C.size++;
|
||||||
|
j.relinkUD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relinkLR();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package com.baeldung.algorithms.sudoku;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DancingLinks {
|
||||||
|
|
||||||
|
private ColumnNode header;
|
||||||
|
private List<DancingNode> answer;
|
||||||
|
|
||||||
|
private void search(int k) {
|
||||||
|
if (header.R == header) {
|
||||||
|
handleSolution(answer);
|
||||||
|
} else {
|
||||||
|
ColumnNode c = selectColumnNodeHeuristic();
|
||||||
|
c.cover();
|
||||||
|
|
||||||
|
for (DancingNode r = c.D; r != c; r = r.D) {
|
||||||
|
answer.add(r);
|
||||||
|
|
||||||
|
for (DancingNode j = r.R; j != r; j = j.R) {
|
||||||
|
j.C.cover();
|
||||||
|
}
|
||||||
|
|
||||||
|
search(k + 1);
|
||||||
|
|
||||||
|
r = answer.remove(answer.size() - 1);
|
||||||
|
c = r.C;
|
||||||
|
|
||||||
|
for (DancingNode j = r.L; j != r; j = j.L) {
|
||||||
|
j.C.uncover();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.uncover();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColumnNode selectColumnNodeHeuristic() {
|
||||||
|
int min = Integer.MAX_VALUE;
|
||||||
|
ColumnNode ret = null;
|
||||||
|
for (ColumnNode c = (ColumnNode) header.R; c != header; c = (ColumnNode) c.R) {
|
||||||
|
if (c.size < min) {
|
||||||
|
min = c.size;
|
||||||
|
ret = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColumnNode makeDLXBoard(boolean[][] grid) {
|
||||||
|
final int COLS = grid[0].length;
|
||||||
|
|
||||||
|
ColumnNode headerNode = new ColumnNode("header");
|
||||||
|
List<ColumnNode> columnNodes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < COLS; i++) {
|
||||||
|
ColumnNode n = new ColumnNode(Integer.toString(i));
|
||||||
|
columnNodes.add(n);
|
||||||
|
headerNode = (ColumnNode) headerNode.hookRight(n);
|
||||||
|
}
|
||||||
|
headerNode = headerNode.R.C;
|
||||||
|
|
||||||
|
for (boolean[] aGrid : grid) {
|
||||||
|
DancingNode prev = null;
|
||||||
|
for (int j = 0; j < COLS; j++) {
|
||||||
|
if (aGrid[j]) {
|
||||||
|
ColumnNode col = columnNodes.get(j);
|
||||||
|
DancingNode newNode = new DancingNode(col);
|
||||||
|
if (prev == null)
|
||||||
|
prev = newNode;
|
||||||
|
col.U.hookDown(newNode);
|
||||||
|
prev = prev.hookRight(newNode);
|
||||||
|
col.size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headerNode.size = COLS;
|
||||||
|
|
||||||
|
return headerNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DancingLinks(boolean[][] cover) {
|
||||||
|
header = makeDLXBoard(cover);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runSolver() {
|
||||||
|
answer = new LinkedList<>();
|
||||||
|
search(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleSolution(List<DancingNode> answer) {
|
||||||
|
int[][] result = parseBoard(answer);
|
||||||
|
printSolution(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int size = 9;
|
||||||
|
|
||||||
|
private int[][] parseBoard(List<DancingNode> answer) {
|
||||||
|
int[][] result = new int[size][size];
|
||||||
|
for (DancingNode n : answer) {
|
||||||
|
DancingNode rcNode = n;
|
||||||
|
int min = Integer.parseInt(rcNode.C.name);
|
||||||
|
for (DancingNode tmp = n.R; tmp != n; tmp = tmp.R) {
|
||||||
|
int val = Integer.parseInt(tmp.C.name);
|
||||||
|
if (val < min) {
|
||||||
|
min = val;
|
||||||
|
rcNode = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int ans1 = Integer.parseInt(rcNode.C.name);
|
||||||
|
int ans2 = Integer.parseInt(rcNode.R.C.name);
|
||||||
|
int r = ans1 / size;
|
||||||
|
int c = ans1 % size;
|
||||||
|
int num = (ans2 % size) + 1;
|
||||||
|
result[r][c] = num;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printSolution(int[][] result) {
|
||||||
|
int N = result.length;
|
||||||
|
for (int[] aResult : result) {
|
||||||
|
StringBuilder ret = new StringBuilder();
|
||||||
|
for (int j = 0; j < N; j++) {
|
||||||
|
ret.append(aResult[j]).append(" ");
|
||||||
|
}
|
||||||
|
System.out.println(ret);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.baeldung.algorithms.sudoku;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class DancingLinksAlgorithm {
|
||||||
|
private static final int BOARD_SIZE = 9;
|
||||||
|
private static final int SUBSECTION_SIZE = 3;
|
||||||
|
private static final int NO_VALUE = 0;
|
||||||
|
private static final int CONSTRAINTS = 4;
|
||||||
|
private static final int MIN_VALUE = 1;
|
||||||
|
private static final int MAX_VALUE = 9;
|
||||||
|
private static final int COVER_START_INDEX = 1;
|
||||||
|
|
||||||
|
private static int[][] board = {
|
||||||
|
{8, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 3, 6, 0, 0, 0, 0, 0},
|
||||||
|
{0, 7, 0, 0, 9, 0, 2, 0, 0},
|
||||||
|
{0, 5, 0, 0, 0, 7, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 4, 5, 7, 0, 0},
|
||||||
|
{0, 0, 0, 1, 0, 0, 0, 3, 0},
|
||||||
|
{0, 0, 1, 0, 0, 0, 0, 6, 8},
|
||||||
|
{0, 0, 8, 5, 0, 0, 0, 1, 0},
|
||||||
|
{0, 9, 0, 0, 0, 0, 4, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
DancingLinksAlgorithm solver = new DancingLinksAlgorithm();
|
||||||
|
solver.solve(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void solve(int[][] board) {
|
||||||
|
boolean[][] cover = initializeExactCoverBoard(board);
|
||||||
|
DancingLinks dlx = new DancingLinks(cover);
|
||||||
|
dlx.runSolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getIndex(int row, int col, int num) {
|
||||||
|
return (row - 1) * BOARD_SIZE * BOARD_SIZE + (col - 1) * BOARD_SIZE + (num - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean[][] createExactCoverBoard() {
|
||||||
|
boolean[][] R = new boolean[BOARD_SIZE * BOARD_SIZE * MAX_VALUE][BOARD_SIZE * BOARD_SIZE * CONSTRAINTS];
|
||||||
|
|
||||||
|
int hBase = 0;
|
||||||
|
|
||||||
|
// Cell constraint.
|
||||||
|
for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) {
|
||||||
|
for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, hBase++) {
|
||||||
|
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) {
|
||||||
|
int index = getIndex(r, c, n);
|
||||||
|
R[index][hBase] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Row constrain.
|
||||||
|
for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) {
|
||||||
|
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
|
||||||
|
for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) {
|
||||||
|
int index = getIndex(r, c1, n);
|
||||||
|
R[index][hBase] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Column constraint.
|
||||||
|
for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) {
|
||||||
|
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
|
||||||
|
for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) {
|
||||||
|
int index = getIndex(r1, c, n);
|
||||||
|
R[index][hBase] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subsection constraint
|
||||||
|
for (int br = COVER_START_INDEX; br <= BOARD_SIZE; br += SUBSECTION_SIZE) {
|
||||||
|
for (int bc = COVER_START_INDEX; bc <= BOARD_SIZE; bc += SUBSECTION_SIZE) {
|
||||||
|
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
|
||||||
|
for (int rDelta = 0; rDelta < SUBSECTION_SIZE; rDelta++) {
|
||||||
|
for (int cDelta = 0; cDelta < SUBSECTION_SIZE; cDelta++) {
|
||||||
|
int index = getIndex(br + rDelta, bc + cDelta, n);
|
||||||
|
R[index][hBase] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean[][] initializeExactCoverBoard(int[][] board) {
|
||||||
|
boolean[][] R = createExactCoverBoard();
|
||||||
|
for (int i = COVER_START_INDEX; i <= BOARD_SIZE; i++) {
|
||||||
|
for (int j = COVER_START_INDEX; j <= BOARD_SIZE; j++) {
|
||||||
|
int n = board[i - 1][j - 1];
|
||||||
|
if (n != NO_VALUE) {
|
||||||
|
for (int num = MIN_VALUE; num <= MAX_VALUE; num++) {
|
||||||
|
if (num != n) {
|
||||||
|
Arrays.fill(R[getIndex(i, j, num)], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.baeldung.algorithms.sudoku;
|
||||||
|
|
||||||
|
class DancingNode {
|
||||||
|
DancingNode L, R, U, D;
|
||||||
|
ColumnNode C;
|
||||||
|
|
||||||
|
DancingNode hookDown(DancingNode n1) {
|
||||||
|
assert (this.C == n1.C);
|
||||||
|
n1.D = this.D;
|
||||||
|
n1.D.U = n1;
|
||||||
|
n1.U = this;
|
||||||
|
this.D = n1;
|
||||||
|
return n1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DancingNode hookRight(DancingNode n1) {
|
||||||
|
n1.R = this.R;
|
||||||
|
n1.R.L = n1;
|
||||||
|
n1.L = this;
|
||||||
|
this.R = n1;
|
||||||
|
return n1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlinkLR() {
|
||||||
|
this.L.R = this.R;
|
||||||
|
this.R.L = this.L;
|
||||||
|
}
|
||||||
|
|
||||||
|
void relinkLR() {
|
||||||
|
this.L.R = this.R.L = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlinkUD() {
|
||||||
|
this.U.D = this.D;
|
||||||
|
this.D.U = this.U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void relinkUD() {
|
||||||
|
this.U.D = this.D.U = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DancingNode() {
|
||||||
|
L = R = U = D = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DancingNode(ColumnNode c) {
|
||||||
|
this();
|
||||||
|
C = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
package com.baeldung.java9.httpclient;
|
||||||
|
|
||||||
|
import jdk.incubator.http.HttpClient;
|
||||||
|
import jdk.incubator.http.HttpRequest;
|
||||||
|
import jdk.incubator.http.HttpResponse;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.collection.IsEmptyCollection.empty;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by adam.
|
||||||
|
*/
|
||||||
|
public class HttpClientTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.headers("Content-Type", "text/plain;charset=UTF-8")
|
||||||
|
.POST(HttpRequest.BodyProcessor.fromString("Sample body"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newBuilder()
|
||||||
|
.proxy(ProxySelector.getDefault())
|
||||||
|
.build()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.body(), containsString("Sample body"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotFollowRedirectWhenSetToDefaultNever() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("http://stackoverflow.com"))
|
||||||
|
.version(HttpClient.Version.HTTP_1_1)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = HttpClient.newBuilder()
|
||||||
|
.build()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_MOVED_PERM));
|
||||||
|
assertThat(response.body(), containsString("https://stackoverflow.com/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFollowRedirectWhenSetToAlways() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("http://stackoverflow.com"))
|
||||||
|
.version(HttpClient.Version.HTTP_1_1)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = HttpClient.newBuilder()
|
||||||
|
.followRedirects(HttpClient.Redirect.ALWAYS)
|
||||||
|
.build()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.finalRequest()
|
||||||
|
.uri()
|
||||||
|
.toString(), equalTo("https://stackoverflow.com/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnOKStatusForAuthenticatedAccess() throws URISyntaxException, IOException, InterruptedException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/basic-auth"))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = HttpClient.newBuilder()
|
||||||
|
.authenticator(new Authenticator() {
|
||||||
|
@Override
|
||||||
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
|
return new PasswordAuthentication("postman", "password".toCharArray());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSendRequestAsync() throws URISyntaxException, InterruptedException, ExecutionException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.headers("Content-Type", "text/plain;charset=UTF-8")
|
||||||
|
.POST(HttpRequest.BodyProcessor.fromString("Sample body"))
|
||||||
|
.build();
|
||||||
|
CompletableFuture<HttpResponse<String>> response = HttpClient.newBuilder()
|
||||||
|
.build()
|
||||||
|
.sendAsync(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.get()
|
||||||
|
.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldUseJustTwoThreadWhenProcessingSendAsyncRequest() throws URISyntaxException, InterruptedException, ExecutionException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
CompletableFuture<HttpResponse<String>> response1 = HttpClient.newBuilder()
|
||||||
|
.executor(Executors.newFixedThreadPool(2))
|
||||||
|
.build()
|
||||||
|
.sendAsync(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
CompletableFuture<HttpResponse<String>> response2 = HttpClient.newBuilder()
|
||||||
|
.executor(Executors.newFixedThreadPool(2))
|
||||||
|
.build()
|
||||||
|
.sendAsync(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
CompletableFuture<HttpResponse<String>> response3 = HttpClient.newBuilder()
|
||||||
|
.executor(Executors.newFixedThreadPool(2))
|
||||||
|
.build()
|
||||||
|
.sendAsync(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
CompletableFuture.allOf(response1, response2, response3)
|
||||||
|
.join();
|
||||||
|
|
||||||
|
assertThat(response1.get()
|
||||||
|
.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response2.get()
|
||||||
|
.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response3.get()
|
||||||
|
.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotStoreCookieWhenPolicyAcceptNone() throws URISyntaxException, IOException, InterruptedException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpClient httpClient = HttpClient.newBuilder()
|
||||||
|
.cookieManager(new CookieManager(null, CookiePolicy.ACCEPT_NONE))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
httpClient.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(httpClient.cookieManager()
|
||||||
|
.get()
|
||||||
|
.getCookieStore()
|
||||||
|
.getCookies(), empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldStoreCookieWhenPolicyAcceptAll() throws URISyntaxException, IOException, InterruptedException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpClient httpClient = HttpClient.newBuilder()
|
||||||
|
.cookieManager(new CookieManager(null, CookiePolicy.ACCEPT_ALL))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
httpClient.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(httpClient.cookieManager()
|
||||||
|
.get()
|
||||||
|
.getCookieStore()
|
||||||
|
.getCookies(), not(empty()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldProcessMultipleRequestViaStream() throws URISyntaxException, ExecutionException, InterruptedException {
|
||||||
|
List<URI> targets = Arrays.asList(new URI("https://postman-echo.com/get?foo1=bar1"), new URI("https://postman-echo.com/get?foo2=bar2"));
|
||||||
|
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
|
||||||
|
List<CompletableFuture<String>> futures = targets.stream()
|
||||||
|
.map(target -> client.sendAsync(HttpRequest.newBuilder(target)
|
||||||
|
.GET()
|
||||||
|
.build(), HttpResponse.BodyHandler.asString())
|
||||||
|
.thenApply(response -> response.body()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||||
|
.join();
|
||||||
|
|
||||||
|
if (futures.get(0)
|
||||||
|
.get()
|
||||||
|
.contains("foo1")) {
|
||||||
|
assertThat(futures.get(0)
|
||||||
|
.get(), containsString("bar1"));
|
||||||
|
assertThat(futures.get(1)
|
||||||
|
.get(), containsString("bar2"));
|
||||||
|
} else {
|
||||||
|
assertThat(futures.get(1)
|
||||||
|
.get(), containsString("bar2"));
|
||||||
|
assertThat(futures.get(1)
|
||||||
|
.get(), containsString("bar1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package com.baeldung.java9.httpclient;
|
||||||
|
|
||||||
|
import jdk.incubator.http.HttpClient;
|
||||||
|
import jdk.incubator.http.HttpRequest;
|
||||||
|
import jdk.incubator.http.HttpResponse;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by adam.
|
||||||
|
*/
|
||||||
|
public class HttpRequestTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldUseHttp2WhenWebsiteUsesHttp2() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://stackoverflow.com"))
|
||||||
|
.version(HttpClient.Version.HTTP_2)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.version(), equalTo(HttpClient.Version.HTTP_2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFallbackToHttp1_1WhenWebsiteDoesNotUseHttp2() throws IOException, InterruptedException, URISyntaxException, NoSuchAlgorithmException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.version(HttpClient.Version.HTTP_2)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.version(), equalTo(HttpClient.Version.HTTP_1_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnStatusOKWhenSendGetRequestWithDummyHeaders() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.headers("key1", "value1", "key2", "value2")
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnStatusOKWhenSendGetRequestTimeoutSet() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.timeout(Duration.of(10, SECONDS))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnNoContentWhenPostWithNoBody() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.POST(HttpRequest.noBody())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnSampleDataContentWhenPostWithBodyText() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.headers("Content-Type", "text/plain;charset=UTF-8")
|
||||||
|
.POST(HttpRequest.BodyProcessor.fromString("Sample request body"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.body(), containsString("Sample request body"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnSampleDataContentWhenPostWithInputStream() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
byte[] sampleData = "Sample request body".getBytes();
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.headers("Content-Type", "text/plain;charset=UTF-8")
|
||||||
|
.POST(HttpRequest.BodyProcessor.fromInputStream(() -> new ByteArrayInputStream(sampleData)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.body(), containsString("Sample request body"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnSampleDataContentWhenPostWithByteArrayProcessorStream() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
byte[] sampleData = "Sample request body".getBytes();
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.headers("Content-Type", "text/plain;charset=UTF-8")
|
||||||
|
.POST(HttpRequest.BodyProcessor.fromByteArray(sampleData))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.body(), containsString("Sample request body"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnSampleDataContentWhenPostWithFileProcessorStream() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/post"))
|
||||||
|
.headers("Content-Type", "text/plain;charset=UTF-8")
|
||||||
|
.POST(HttpRequest.BodyProcessor.fromFile(Paths.get("src/test/resources/sample.txt")))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.body(), containsString("Sample file content"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.baeldung.java9.httpclient;
|
||||||
|
|
||||||
|
import jdk.incubator.http.HttpClient;
|
||||||
|
import jdk.incubator.http.HttpRequest;
|
||||||
|
import jdk.incubator.http.HttpResponse;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isEmptyString;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by adam.
|
||||||
|
*/
|
||||||
|
public class HttpResponseTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("https://postman-echo.com/get"))
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
|
||||||
|
assertThat(response.body(), not(isEmptyString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldResponseURIDifferentThanRequestUIRWhenRedirect() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(new URI("http://stackoverflow.com"))
|
||||||
|
.version(HttpClient.Version.HTTP_1_1)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
HttpResponse<String> response = HttpClient.newBuilder()
|
||||||
|
.followRedirects(HttpClient.Redirect.ALWAYS)
|
||||||
|
.build()
|
||||||
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
|
assertThat(request.uri()
|
||||||
|
.toString(), equalTo("http://stackoverflow.com"));
|
||||||
|
assertThat(response.uri()
|
||||||
|
.toString(), equalTo("https://stackoverflow.com/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.concurrent.prioritytaskexecution;
|
||||||
|
|
||||||
|
public class Job implements Runnable {
|
||||||
|
private String jobName;
|
||||||
|
private JobPriority jobPriority;
|
||||||
|
|
||||||
|
public Job(String jobName, JobPriority jobPriority) {
|
||||||
|
this.jobName = jobName;
|
||||||
|
this.jobPriority = jobPriority != null ? jobPriority : JobPriority.MEDIUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JobPriority getJobPriority() {
|
||||||
|
return jobPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
System.out.println("Job:" + jobName + " Priority:" + jobPriority);
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.concurrent.prioritytaskexecution;
|
||||||
|
|
||||||
|
public enum JobPriority {
|
||||||
|
HIGH,
|
||||||
|
MEDIUM,
|
||||||
|
LOW
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.concurrent.prioritytaskexecution;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.PriorityBlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class PriorityJobScheduler {
|
||||||
|
|
||||||
|
private ExecutorService priorityJobPoolExecutor;
|
||||||
|
private ExecutorService priorityJobScheduler;
|
||||||
|
private PriorityBlockingQueue<Runnable> priorityQueue;
|
||||||
|
|
||||||
|
public PriorityJobScheduler(Integer poolSize, Integer queueSize) {
|
||||||
|
priorityJobPoolExecutor = Executors.newFixedThreadPool(poolSize);
|
||||||
|
Comparator<? super Job> jobComparator = Comparator.comparing(Job::getJobPriority);
|
||||||
|
priorityQueue = new PriorityBlockingQueue<Runnable>(queueSize,
|
||||||
|
(Comparator<? super Runnable>) jobComparator);
|
||||||
|
|
||||||
|
priorityJobScheduler = Executors.newSingleThreadExecutor();
|
||||||
|
priorityJobScheduler.execute(()->{
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
priorityJobPoolExecutor.execute(priorityQueue.take());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scheduleJob(Job job) {
|
||||||
|
priorityQueue.add(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQueuedTaskCount() {
|
||||||
|
return priorityQueue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void close(ExecutorService scheduler) {
|
||||||
|
scheduler.shutdown();
|
||||||
|
try {
|
||||||
|
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeScheduler() {
|
||||||
|
close(priorityJobPoolExecutor);
|
||||||
|
close(priorityJobScheduler);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.baeldung.concurrent.waitandnotify;
|
package com.baeldung.concurrent.waitandnotify;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
public class Data {
|
public class Data {
|
||||||
private String packet;
|
private String packet;
|
||||||
|
|
||||||
@@ -14,6 +12,7 @@ public class Data {
|
|||||||
try {
|
try {
|
||||||
wait();
|
wait();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
System.out.println("Thread Interrupted");
|
System.out.println("Thread Interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,6 +27,7 @@ public class Data {
|
|||||||
try {
|
try {
|
||||||
wait();
|
wait();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
System.out.println("Thread Interrupted");
|
System.out.println("Thread Interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -20,6 +20,7 @@ public class Receiver implements Runnable {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
|
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
System.out.println("Thread Interrupted");
|
System.out.println("Thread Interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public class Sender implements Runnable {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
|
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
System.out.println("Thread Interrupted");
|
System.out.println("Thread Interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.concurrent.prioritytaskexecution;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class PriorityJobSchedulerUnitTest {
|
||||||
|
private static int POOL_SIZE = 1;
|
||||||
|
private static int QUEUE_SIZE = 10;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked() {
|
||||||
|
Job job1 = new Job("Job1", JobPriority.LOW);
|
||||||
|
Job job2 = new Job("Job2", JobPriority.MEDIUM);
|
||||||
|
Job job3 = new Job("Job3", JobPriority.HIGH);
|
||||||
|
Job job4 = new Job("Job4", JobPriority.MEDIUM);
|
||||||
|
Job job5 = new Job("Job5", JobPriority.LOW);
|
||||||
|
Job job6 = new Job("Job6", JobPriority.HIGH);
|
||||||
|
|
||||||
|
PriorityJobScheduler pjs = new PriorityJobScheduler(POOL_SIZE, QUEUE_SIZE);
|
||||||
|
|
||||||
|
pjs.scheduleJob(job1);
|
||||||
|
pjs.scheduleJob(job2);
|
||||||
|
pjs.scheduleJob(job3);
|
||||||
|
pjs.scheduleJob(job4);
|
||||||
|
pjs.scheduleJob(job5);
|
||||||
|
pjs.scheduleJob(job6);
|
||||||
|
|
||||||
|
// ensure no tasks is pending before closing the scheduler
|
||||||
|
while (pjs.getQueuedTaskCount() != 0);
|
||||||
|
|
||||||
|
// delay to avoid job sleep (added for demo) being interrupted
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pjs.closeScheduler();
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -57,7 +57,8 @@ public class NetworkIntegrationTest {
|
|||||||
sender.join();
|
sender.join();
|
||||||
receiver.join();
|
receiver.join();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
Thread.currentThread().interrupt();
|
||||||
|
System.out.println("Thread Interrupted");
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(expected, outContent.toString());
|
assertEquals(expected, outContent.toString());
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
public interface Channel {
|
||||||
|
public void update(Object o);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NewsAgency {
|
||||||
|
private String news;
|
||||||
|
private List<Channel> channels = new ArrayList<>();
|
||||||
|
|
||||||
|
public void addObserver(Channel channel) {
|
||||||
|
this.channels.add(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeObserver(Channel channel) {
|
||||||
|
this.channels.remove(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNews(String news) {
|
||||||
|
this.news = news;
|
||||||
|
for (Channel channel : this.channels) {
|
||||||
|
channel.update(this.news);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
public class NewsChannel implements Channel {
|
||||||
|
|
||||||
|
private String news;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Object news) {
|
||||||
|
this.setNews((String) news);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNews() {
|
||||||
|
return news;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNews(String news) {
|
||||||
|
this.news = news;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
|
public class ONewsAgency extends Observable {
|
||||||
|
private String news;
|
||||||
|
|
||||||
|
public void setNews(String news) {
|
||||||
|
this.news = news;
|
||||||
|
setChanged();
|
||||||
|
notifyObservers(news);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
public class ONewsChannel implements Observer {
|
||||||
|
|
||||||
|
private String news;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object news) {
|
||||||
|
this.setNews((String) news);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNews() {
|
||||||
|
return news;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNews(String news) {
|
||||||
|
this.news = news;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.beans.PropertyChangeSupport;
|
||||||
|
|
||||||
|
public class PCLNewsAgency {
|
||||||
|
private String news;
|
||||||
|
|
||||||
|
private PropertyChangeSupport support;
|
||||||
|
|
||||||
|
public PCLNewsAgency() {
|
||||||
|
support = new PropertyChangeSupport(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
support.addPropertyChangeListener(pcl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||||
|
support.removePropertyChangeListener(pcl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNews(String value) {
|
||||||
|
support.firePropertyChange("news", this.news, value);
|
||||||
|
this.news = value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
|
||||||
|
public class PCLNewsChannel implements PropertyChangeListener {
|
||||||
|
|
||||||
|
private String news;
|
||||||
|
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
this.setNews((String) evt.getNewValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNews() {
|
||||||
|
return news;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNews(String news) {
|
||||||
|
this.news = news;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.javac;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Data implements Serializable {
|
||||||
|
static List<String> textList = new ArrayList();
|
||||||
|
|
||||||
|
private static void addText() {
|
||||||
|
textList.add("baeldung");
|
||||||
|
textList.add(".");
|
||||||
|
textList.add("com");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getTextList() {
|
||||||
|
this.addText();
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
String firstElement = (String) textList.get(0);
|
||||||
|
switch (firstElement) {
|
||||||
|
case "baeldung":
|
||||||
|
result.add("baeldung");
|
||||||
|
case "com":
|
||||||
|
result.add("com");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-d javac-target -verbose
|
||||||
|
com/baeldung/javac/Data.java
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-d javac-target
|
||||||
|
-verbose
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
com/baeldung/javac/Data.java
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-d javac-target
|
||||||
|
-Xlint:rawtypes,unchecked,static,cast,serial,fallthrough
|
||||||
|
com/baeldung/javac/Data.java
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.designpatterns.observer;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.designpatterns.observer.NewsAgency;
|
||||||
|
import com.baeldung.designpatterns.observer.NewsChannel;
|
||||||
|
|
||||||
|
public class ObserverIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenChangingNewsAgencyState_thenNewsChannelNotified() {
|
||||||
|
|
||||||
|
NewsAgency observable = new NewsAgency();
|
||||||
|
NewsChannel observer = new NewsChannel();
|
||||||
|
|
||||||
|
observable.addObserver(observer);
|
||||||
|
|
||||||
|
observable.setNews("news");
|
||||||
|
assertEquals(observer.getNews(), "news");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenChangingONewsAgencyState_thenONewsChannelNotified() {
|
||||||
|
|
||||||
|
ONewsAgency observable = new ONewsAgency();
|
||||||
|
ONewsChannel observer = new ONewsChannel();
|
||||||
|
|
||||||
|
observable.addObserver(observer);
|
||||||
|
|
||||||
|
observable.setNews("news");
|
||||||
|
assertEquals(observer.getNews(), "news");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenChangingPCLNewsAgencyState_thenONewsChannelNotified() {
|
||||||
|
|
||||||
|
PCLNewsAgency observable = new PCLNewsAgency();
|
||||||
|
PCLNewsChannel observer = new PCLNewsChannel();
|
||||||
|
|
||||||
|
observable.addPropertyChangeListener(observer);
|
||||||
|
|
||||||
|
observable.setNews("news");
|
||||||
|
assertEquals(observer.getNews(), "news");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.baeldung.guava.memoizer;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class CostlySupplier {
|
||||||
|
|
||||||
|
public static BigInteger generateBigNumber() {
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(2);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
return new BigInteger("12345");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user