Merge branch 'master' of github.com:eugenp/tutorials
This commit is contained in:
commit
32bdaa1d49
@ -13,6 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
||||
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
|
||||
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
|
||||
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
|
||||
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
|
||||
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
||||
|
@ -15,9 +15,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
||||
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
||||
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
|
||||
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
||||
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
|
||||
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
|
||||
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
||||
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
||||
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4) [[next -->]](/../algorithms-miscellaneous-6)
|
||||
|
||||
|
@ -25,12 +25,6 @@
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pl.allegro.finance</groupId>
|
||||
<artifactId>tradukisto</artifactId>
|
||||
|
10
algorithms-miscellaneous-6/README.md
Normal file
10
algorithms-miscellaneous-6/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
|
||||
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
|
||||
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
|
||||
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
|
||||
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
||||
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
||||
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-5)
|
@ -18,10 +18,35 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-commons</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${org.assertj.core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<guava.version>28.1-jre</guava.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
<junit.platform.version>1.6.0</junit.platform.version>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
@ -1,13 +1,13 @@
|
||||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
public class HeapNode {
|
||||
|
||||
int element;
|
||||
int arrayIndex;
|
||||
int nextElementIndex = 1;
|
||||
|
||||
public HeapNode(int element, int arrayIndex) {
|
||||
this.element = element;
|
||||
this.arrayIndex = arrayIndex;
|
||||
}
|
||||
}
|
||||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
public class HeapNode {
|
||||
|
||||
int element;
|
||||
int arrayIndex;
|
||||
int nextElementIndex = 1;
|
||||
|
||||
public HeapNode(int element, int arrayIndex) {
|
||||
this.element = element;
|
||||
this.arrayIndex = arrayIndex;
|
||||
}
|
||||
}
|
@ -1,88 +1,88 @@
|
||||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
public class MinHeap {
|
||||
|
||||
HeapNode[] heapNodes;
|
||||
|
||||
public MinHeap(HeapNode heapNodes[]) {
|
||||
this.heapNodes = heapNodes;
|
||||
heapifyFromLastLeafsParent();
|
||||
}
|
||||
|
||||
void heapifyFromLastLeafsParent() {
|
||||
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
|
||||
while (lastLeafsParentIndex >= 0) {
|
||||
heapify(lastLeafsParentIndex);
|
||||
lastLeafsParentIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
void heapify(int index) {
|
||||
int leftNodeIndex = getLeftNodeIndex(index);
|
||||
int rightNodeIndex = getRightNodeIndex(index);
|
||||
int smallestElementIndex = index;
|
||||
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
|
||||
smallestElementIndex = leftNodeIndex;
|
||||
}
|
||||
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
|
||||
smallestElementIndex = rightNodeIndex;
|
||||
}
|
||||
if (smallestElementIndex != index) {
|
||||
swap(index, smallestElementIndex);
|
||||
heapify(smallestElementIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int getParentNodeIndex(int index) {
|
||||
return (index - 1) / 2;
|
||||
}
|
||||
|
||||
int getLeftNodeIndex(int index) {
|
||||
return (2 * index + 1);
|
||||
}
|
||||
|
||||
int getRightNodeIndex(int index) {
|
||||
return (2 * index + 2);
|
||||
}
|
||||
|
||||
HeapNode getRootNode() {
|
||||
return heapNodes[0];
|
||||
}
|
||||
|
||||
void heapifyFromRoot() {
|
||||
heapify(0);
|
||||
}
|
||||
|
||||
void swap(int i, int j) {
|
||||
HeapNode temp = heapNodes[i];
|
||||
heapNodes[i] = heapNodes[j];
|
||||
heapNodes[j] = temp;
|
||||
}
|
||||
|
||||
static int[] merge(int[][] array) {
|
||||
HeapNode[] heapNodes = new HeapNode[array.length];
|
||||
int resultingArraySize = 0;
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
HeapNode node = new HeapNode(array[i][0], i);
|
||||
heapNodes[i] = node;
|
||||
resultingArraySize += array[i].length;
|
||||
}
|
||||
|
||||
MinHeap minHeap = new MinHeap(heapNodes);
|
||||
int[] resultingArray = new int[resultingArraySize];
|
||||
|
||||
for (int i = 0; i < resultingArraySize; i++) {
|
||||
HeapNode root = minHeap.getRootNode();
|
||||
resultingArray[i] = root.element;
|
||||
|
||||
if (root.nextElementIndex < array[root.arrayIndex].length) {
|
||||
root.element = array[root.arrayIndex][root.nextElementIndex++];
|
||||
} else {
|
||||
root.element = Integer.MAX_VALUE;
|
||||
}
|
||||
minHeap.heapifyFromRoot();
|
||||
}
|
||||
return resultingArray;
|
||||
}
|
||||
}
|
||||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
public class MinHeap {
|
||||
|
||||
HeapNode[] heapNodes;
|
||||
|
||||
public MinHeap(HeapNode heapNodes[]) {
|
||||
this.heapNodes = heapNodes;
|
||||
heapifyFromLastLeafsParent();
|
||||
}
|
||||
|
||||
void heapifyFromLastLeafsParent() {
|
||||
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
|
||||
while (lastLeafsParentIndex >= 0) {
|
||||
heapify(lastLeafsParentIndex);
|
||||
lastLeafsParentIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
void heapify(int index) {
|
||||
int leftNodeIndex = getLeftNodeIndex(index);
|
||||
int rightNodeIndex = getRightNodeIndex(index);
|
||||
int smallestElementIndex = index;
|
||||
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
|
||||
smallestElementIndex = leftNodeIndex;
|
||||
}
|
||||
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
|
||||
smallestElementIndex = rightNodeIndex;
|
||||
}
|
||||
if (smallestElementIndex != index) {
|
||||
swap(index, smallestElementIndex);
|
||||
heapify(smallestElementIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int getParentNodeIndex(int index) {
|
||||
return (index - 1) / 2;
|
||||
}
|
||||
|
||||
int getLeftNodeIndex(int index) {
|
||||
return (2 * index + 1);
|
||||
}
|
||||
|
||||
int getRightNodeIndex(int index) {
|
||||
return (2 * index + 2);
|
||||
}
|
||||
|
||||
HeapNode getRootNode() {
|
||||
return heapNodes[0];
|
||||
}
|
||||
|
||||
void heapifyFromRoot() {
|
||||
heapify(0);
|
||||
}
|
||||
|
||||
void swap(int i, int j) {
|
||||
HeapNode temp = heapNodes[i];
|
||||
heapNodes[i] = heapNodes[j];
|
||||
heapNodes[j] = temp;
|
||||
}
|
||||
|
||||
static int[] merge(int[][] array) {
|
||||
HeapNode[] heapNodes = new HeapNode[array.length];
|
||||
int resultingArraySize = 0;
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
HeapNode node = new HeapNode(array[i][0], i);
|
||||
heapNodes[i] = node;
|
||||
resultingArraySize += array[i].length;
|
||||
}
|
||||
|
||||
MinHeap minHeap = new MinHeap(heapNodes);
|
||||
int[] resultingArray = new int[resultingArraySize];
|
||||
|
||||
for (int i = 0; i < resultingArraySize; i++) {
|
||||
HeapNode root = minHeap.getRootNode();
|
||||
resultingArray[i] = root.element;
|
||||
|
||||
if (root.nextElementIndex < array[root.arrayIndex].length) {
|
||||
root.element = array[root.arrayIndex][root.nextElementIndex++];
|
||||
} else {
|
||||
root.element = Integer.MAX_VALUE;
|
||||
}
|
||||
minHeap.heapifyFromRoot();
|
||||
}
|
||||
return resultingArray;
|
||||
}
|
||||
}
|
@ -1,22 +1,22 @@
|
||||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MinHeapUnitTest {
|
||||
|
||||
private final int[][] inputArray = { { 0, 6 }, { 1, 5, 10, 100 }, { 2, 4, 200, 650 } };
|
||||
private final int[] expectedArray = { 0, 1, 2, 4, 5, 6, 10, 100, 200, 650 };
|
||||
|
||||
@Test
|
||||
public void givenSortedArrays_whenMerged_thenShouldReturnASingleSortedarray() {
|
||||
int[] resultArray = MinHeap.merge(inputArray);
|
||||
|
||||
assertThat(resultArray.length, is(equalTo(10)));
|
||||
assertThat(resultArray, is(equalTo(expectedArray)));
|
||||
}
|
||||
|
||||
}
|
||||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MinHeapUnitTest {
|
||||
|
||||
private final int[][] inputArray = { { 0, 6 }, { 1, 5, 10, 100 }, { 2, 4, 200, 650 } };
|
||||
private final int[] expectedArray = { 0, 1, 2, 4, 5, 6, 10, 100, 200, 650 };
|
||||
|
||||
@Test
|
||||
public void givenSortedArrays_whenMerged_thenShouldReturnASingleSortedarray() {
|
||||
int[] resultArray = MinHeap.merge(inputArray);
|
||||
|
||||
assertThat(resultArray.length, is(equalTo(10)));
|
||||
assertThat(resultArray, is(equalTo(expectedArray)));
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
|
||||
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||
- [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting)
|
||||
- [Partitioning and Sorting Arrays with Many Repeated Entries](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
|
||||
- More articles: [[<-- prev]](/algorithms-sorting)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.algorithms.sort.bynumber;
|
||||
package com.baeldung.algorithms.bynumber;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.baeldung.algorithms.sort.bynumber;
|
||||
package com.baeldung.algorithms.bynumber;
|
||||
|
||||
import com.baeldung.algorithms.sort.bynumber.NaturalOrderComparators;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
@ -11,10 +11,7 @@ This module contains articles about sorting algorithms.
|
||||
- [Heap Sort in Java](https://www.baeldung.com/java-heap-sort)
|
||||
- [Shell Sort in Java](https://www.baeldung.com/java-shell-sort)
|
||||
- [Counting Sort in Java](https://www.baeldung.com/java-counting-sort)
|
||||
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||
- [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting)
|
||||
- [Selection Sort in Java](https://www.baeldung.com/java-selection-sort)
|
||||
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||
- [Radix Sort in Java](https://www.baeldung.com/java-radix-sort)
|
||||
- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
|
||||
- [Bucket Sort in Java](https://www.baeldung.com/java-bucket-sort)
|
||||
- More articles: [[next -->]](/algorithms-sorintg-2)
|
||||
|
@ -1,3 +0,0 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Intro to OData with Olingo](https://www.baeldung.com/olingo)
|
@ -10,9 +10,9 @@
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-1</relativePath>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -1,11 +1,14 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.*;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.apache.shiro.authc.LockedAccountException;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.realm.text.IniRealm;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -1,16 +1,24 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.apache.shiro.authc.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
public class MyCustomRealm extends JdbcRealm {
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
package com.baeldung.shiro.permissions.custom;
|
||||
|
||||
import com.baeldung.MyCustomRealm;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.*;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.apache.shiro.authc.LockedAccountException;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.config.Ini;
|
||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.realm.text.IniRealm;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
6
atomikos/README.md
Normal file
6
atomikos/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
## Atomikos
|
||||
This module contains articles about Atomikos
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [A Guide to Atomikos](https://www.baeldung.com/java-atomikos)
|
119
atomikos/pom.xml
Normal file
119
atomikos/pom.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>atomikos</artifactId>
|
||||
<name>atomikos</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jdbc</artifactId>
|
||||
<version>${atomikos-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jms</artifactId>
|
||||
<version>${atomikos-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-hibernate4</artifactId>
|
||||
<version>${atomikos-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>1.11.23.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>jta</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-core</artifactId>
|
||||
<version>5.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<version>10.8.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- the JTA API -->
|
||||
<dependency>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>jta</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jta_1.0.1B_spec</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>2.0.1.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.1.2.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>javax.el-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.web</groupId>
|
||||
<artifactId>javax.el</artifactId>
|
||||
<version>2.2.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<atomikos-version>5.0.6</atomikos-version>
|
||||
<spring-version>5.1.6.RELEASE</spring-version>
|
||||
<hibernate.version>5.4.3.Final</hibernate.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,53 @@
|
||||
package com.baeldung.atomikos.direct;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||
|
||||
public class Application {
|
||||
|
||||
private DataSource inventoryDataSource;
|
||||
private DataSource orderDataSource;
|
||||
|
||||
public Application(DataSource inventoryDataSource, DataSource orderDataSource) {
|
||||
this.inventoryDataSource = inventoryDataSource;
|
||||
this.orderDataSource = orderDataSource;
|
||||
}
|
||||
|
||||
public void placeOrder(String productId, int amount) throws Exception {
|
||||
|
||||
UserTransactionImp utx = new UserTransactionImp();
|
||||
String orderId = UUID.randomUUID()
|
||||
.toString();
|
||||
boolean rollback = false;
|
||||
try {
|
||||
utx.begin();
|
||||
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||
Connection orderConnection = orderDataSource.getConnection();
|
||||
Statement s1 = inventoryConnection.createStatement();
|
||||
String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'";
|
||||
s1.executeUpdate(q1);
|
||||
s1.close();
|
||||
Statement s2 = orderConnection.createStatement();
|
||||
String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )";
|
||||
s2.executeUpdate(q2);
|
||||
s2.close();
|
||||
inventoryConnection.close();
|
||||
orderConnection.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
rollback = true;
|
||||
} finally {
|
||||
if (!rollback)
|
||||
utx.commit();
|
||||
else
|
||||
utx.rollback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.baeldung.atomikos.spring;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class Application {
|
||||
|
||||
private DataSource inventoryDataSource;
|
||||
private DataSource orderDataSource;
|
||||
|
||||
public Application(DataSource inventoryDataSource, DataSource orderDataSource) {
|
||||
this.inventoryDataSource = inventoryDataSource;
|
||||
this.orderDataSource = orderDataSource;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void placeOrder(String productId, int amount) throws Exception {
|
||||
|
||||
String orderId = UUID.randomUUID()
|
||||
.toString();
|
||||
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||
Connection orderConnection = orderDataSource.getConnection();
|
||||
Statement s1 = inventoryConnection.createStatement();
|
||||
String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'";
|
||||
s1.executeUpdate(q1);
|
||||
s1.close();
|
||||
Statement s2 = orderConnection.createStatement();
|
||||
String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )";
|
||||
s2.executeUpdate(q2);
|
||||
s2.close();
|
||||
inventoryConnection.close();
|
||||
orderConnection.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.baeldung.atomikos.spring.config;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||
import com.baeldung.atomikos.spring.Application;
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
public class Config {
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
public AtomikosDataSourceBean inventoryDataSource() {
|
||||
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||
dataSource.setLocalTransactionMode(true);
|
||||
dataSource.setUniqueResourceName("db1");
|
||||
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||
Properties xaProperties = new Properties();
|
||||
xaProperties.put("databaseName", "db1");
|
||||
xaProperties.put("createDatabase", "create");
|
||||
dataSource.setXaProperties(xaProperties);
|
||||
dataSource.setPoolSize(10);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
public AtomikosDataSourceBean orderDataSource() {
|
||||
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||
dataSource.setLocalTransactionMode(true);
|
||||
dataSource.setUniqueResourceName("db2");
|
||||
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||
Properties xaProperties = new Properties();
|
||||
xaProperties.put("databaseName", "db2");
|
||||
xaProperties.put("createDatabase", "create");
|
||||
dataSource.setXaProperties(xaProperties);
|
||||
dataSource.setPoolSize(10);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
public UserTransactionManager userTransactionManager() throws SystemException {
|
||||
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||
userTransactionManager.setTransactionTimeout(300);
|
||||
userTransactionManager.setForceShutdown(true);
|
||||
return userTransactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JtaTransactionManager jtaTransactionManager() throws SystemException {
|
||||
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
|
||||
jtaTransactionManager.setTransactionManager(userTransactionManager());
|
||||
jtaTransactionManager.setUserTransaction(userTransactionManager());
|
||||
return jtaTransactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Application application() {
|
||||
return new Application(inventoryDataSource(), orderDataSource());
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.baeldung.atomikos.spring.jpa;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.atomikos.spring.jpa.inventory.Inventory;
|
||||
import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository;
|
||||
import com.baeldung.atomikos.spring.jpa.order.Order;
|
||||
import com.baeldung.atomikos.spring.jpa.order.OrderRepository;
|
||||
|
||||
public class Application {
|
||||
|
||||
@Autowired
|
||||
private InventoryRepository inventoryRepository;
|
||||
|
||||
@Autowired
|
||||
private OrderRepository orderRepository;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void placeOrder(String productId, int amount) throws Exception {
|
||||
|
||||
String orderId = UUID.randomUUID()
|
||||
.toString();
|
||||
Inventory inventory = inventoryRepository.findOne(productId);
|
||||
inventory.setBalance(inventory.getBalance() - amount);
|
||||
inventoryRepository.save(inventory);
|
||||
Order order = new Order();
|
||||
order.setOrderId(orderId);
|
||||
order.setProductId(productId);
|
||||
order.setAmount(new Long(amount));
|
||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||
Validator validator = factory.getValidator();
|
||||
Set<ConstraintViolation<Order>> violations = validator.validate(order);
|
||||
if (violations.size() > 0)
|
||||
throw new Exception("Invalid instance of an order.");
|
||||
orderRepository.save(order);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.baeldung.atomikos.spring.jpa.config;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||
import com.baeldung.atomikos.spring.jpa.Application;
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
public class Config {
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
public UserTransactionManager userTransactionManager() throws SystemException {
|
||||
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||
userTransactionManager.setTransactionTimeout(300);
|
||||
userTransactionManager.setForceShutdown(true);
|
||||
return userTransactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JtaTransactionManager transactionManager() throws SystemException {
|
||||
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
|
||||
jtaTransactionManager.setTransactionManager(userTransactionManager());
|
||||
jtaTransactionManager.setUserTransaction(userTransactionManager());
|
||||
return jtaTransactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Application application() {
|
||||
return new Application();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "INVENTORY")
|
||||
public class Inventory {
|
||||
|
||||
@Id
|
||||
private String productId;
|
||||
private Long balance;
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public Long getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(Long balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
|
||||
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.inventory", entityManagerFactoryRef = "inventoryEntityManager", transactionManagerRef = "transactionManager")
|
||||
public class InventoryConfig {
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
public AtomikosDataSourceBean inventoryDataSource() {
|
||||
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||
dataSource.setLocalTransactionMode(true);
|
||||
dataSource.setUniqueResourceName("db1");
|
||||
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||
Properties xaProperties = new Properties();
|
||||
xaProperties.put("databaseName", "db1");
|
||||
xaProperties.put("createDatabase", "create");
|
||||
dataSource.setXaProperties(xaProperties);
|
||||
dataSource.setPoolSize(10);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityManagerFactory inventoryEntityManager() {
|
||||
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||
factory.setJpaVendorAdapter(vendorAdapter);
|
||||
factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.inventory");
|
||||
factory.setDataSource(inventoryDataSource());
|
||||
Properties jpaProperties = new Properties();
|
||||
//jpaProperties.put("hibernate.show_sql", "true");
|
||||
//jpaProperties.put("hibernate.format_sql", "true");
|
||||
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
|
||||
jpaProperties.put("hibernate.current_session_context_class", "jta");
|
||||
jpaProperties.put("javax.persistence.transactionType", "jta");
|
||||
jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup");
|
||||
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
|
||||
factory.setJpaProperties(jpaProperties);
|
||||
factory.afterPropertiesSet();
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface InventoryRepository extends JpaRepository<Inventory, String> {
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.baeldung.atomikos.spring.jpa.order;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.Max;
|
||||
|
||||
@Entity
|
||||
@Table(name = "ORDERS")
|
||||
public class Order {
|
||||
|
||||
@Id
|
||||
private String orderId;
|
||||
private String productId;
|
||||
@Max(5)
|
||||
private Long amount;
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public Long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.baeldung.atomikos.spring.jpa.order;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
|
||||
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager")
|
||||
public class OrderConfig {
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
public AtomikosDataSourceBean orderDataSource() {
|
||||
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||
dataSource.setLocalTransactionMode(true);
|
||||
dataSource.setUniqueResourceName("db2");
|
||||
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||
Properties xaProperties = new Properties();
|
||||
xaProperties.put("databaseName", "db2");
|
||||
xaProperties.put("createDatabase", "create");
|
||||
dataSource.setXaProperties(xaProperties);
|
||||
dataSource.setPoolSize(10);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityManagerFactory orderEntityManager() {
|
||||
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||
factory.setJpaVendorAdapter(vendorAdapter);
|
||||
factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.order");
|
||||
factory.setDataSource(orderDataSource());
|
||||
Properties jpaProperties = new Properties();
|
||||
//jpaProperties.put("hibernate.show_sql", "true");
|
||||
//jpaProperties.put("hibernate.format_sql", "true");
|
||||
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
|
||||
jpaProperties.put("hibernate.current_session_context_class", "jta");
|
||||
jpaProperties.put("javax.persistence.transactionType", "jta");
|
||||
jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup");
|
||||
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
|
||||
factory.setJpaProperties(jpaProperties);
|
||||
factory.afterPropertiesSet();
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.atomikos.spring.jpa.order;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface OrderRepository extends JpaRepository<Order, String> {
|
||||
|
||||
}
|
10
atomikos/src/main/resources/schema.sql
Normal file
10
atomikos/src/main/resources/schema.sql
Normal file
@ -0,0 +1,10 @@
|
||||
CREATE TABLE INVENTORY (
|
||||
productId VARCHAR PRIMARY KEY,
|
||||
balance INT
|
||||
);
|
||||
|
||||
CREATE TABLE ORDERS (
|
||||
orderId VARCHAR PRIMARY KEY,
|
||||
productId VARCHAR,
|
||||
amount INT NOT NULL CHECK (amount <= 5)
|
||||
);
|
1
atomikos/src/main/resources/transactions.properties
Normal file
1
atomikos/src/main/resources/transactions.properties
Normal file
@ -0,0 +1 @@
|
||||
com.atomikos.icatch.file=logs
|
@ -0,0 +1,118 @@
|
||||
package com.baeldung.atomikos.direct;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||
|
||||
public class ApplicationUnitTest {
|
||||
|
||||
private static DataSource inventoryDataSource;
|
||||
private static DataSource orderDataSource;
|
||||
|
||||
private static String productId = UUID.randomUUID()
|
||||
.toString();
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPlaceOrderSuccess() throws Exception {
|
||||
int amount = 1;
|
||||
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||
Application application = new Application(inventoryDataSource, orderDataSource);
|
||||
application.placeOrder(productId, amount);
|
||||
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||
assertEquals(initialBalance - amount, finalBalance);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPlaceOrderFailure() throws Exception {
|
||||
int amount = 10;
|
||||
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||
Application application = new Application(inventoryDataSource, orderDataSource);
|
||||
application.placeOrder(productId, amount);
|
||||
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||
assertEquals(initialBalance, finalBalance);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws SQLException {
|
||||
|
||||
inventoryDataSource = getDataSource("db1");
|
||||
orderDataSource = getDataSource("db2");
|
||||
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||
Connection orderConnection = orderDataSource.getConnection();
|
||||
String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )";
|
||||
String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )";
|
||||
Statement s1 = inventoryConnection.createStatement();
|
||||
try {
|
||||
s1.executeUpdate(createInventoryTable);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Inventory table exists");
|
||||
}
|
||||
try {
|
||||
s1.executeUpdate(createInventoryRow);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Product row exists");
|
||||
}
|
||||
s1.close();
|
||||
String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )";
|
||||
Statement s2 = orderConnection.createStatement();
|
||||
try {
|
||||
s2.executeUpdate(createOrderTable);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Orders table exists");
|
||||
}
|
||||
s2.close();
|
||||
inventoryConnection.close();
|
||||
orderConnection.close();
|
||||
}
|
||||
|
||||
private static DataSource getDataSource(String db) {
|
||||
|
||||
DataSource ds;
|
||||
AtomikosDataSourceBean ads = new AtomikosDataSourceBean();
|
||||
ads.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||
Properties properties = new Properties();
|
||||
properties.put("databaseName", db);
|
||||
properties.put("createDatabase", "create");
|
||||
ads.setXaProperties(properties);
|
||||
ads.setUniqueResourceName(db);
|
||||
ads.setPoolSize(10); // optional
|
||||
ads.setBorrowConnectionTimeout(10); // optional
|
||||
ds = ads;
|
||||
return ds;
|
||||
|
||||
}
|
||||
|
||||
private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception {
|
||||
|
||||
UserTransactionImp utx = new UserTransactionImp();
|
||||
utx.begin();
|
||||
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||
Statement s1 = inventoryConnection.createStatement();
|
||||
String q1 = "select balance from Inventory where productId='" + productId + "'";
|
||||
ResultSet rs1 = s1.executeQuery(q1);
|
||||
if (rs1 == null || !rs1.next())
|
||||
throw new Exception("Product not found: " + productId);
|
||||
long balance = rs1.getLong(1);
|
||||
inventoryConnection.close();
|
||||
utx.commit();
|
||||
return balance;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.baeldung.atomikos.spring;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.atomikos.spring.config.Config;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { Config.class })
|
||||
public class ApplicationUnitTest {
|
||||
|
||||
private static String productId = UUID.randomUUID()
|
||||
.toString();
|
||||
|
||||
@Autowired
|
||||
Application application;
|
||||
|
||||
@Autowired
|
||||
DataSource inventoryDataSource;
|
||||
|
||||
@Autowired
|
||||
DataSource orderDataSource;
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPlaceOrderSuccess() throws Exception {
|
||||
int amount = 1;
|
||||
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||
application.placeOrder(productId, amount);
|
||||
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||
assertEquals(initialBalance - amount, finalBalance);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPlaceOrderFailure() throws Exception {
|
||||
int amount = 10;
|
||||
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||
try {
|
||||
application.placeOrder(productId, amount);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||
assertEquals(initialBalance, finalBalance);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws SQLException {
|
||||
|
||||
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||
Connection orderConnection = orderDataSource.getConnection();
|
||||
String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )";
|
||||
String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )";
|
||||
Statement s1 = inventoryConnection.createStatement();
|
||||
try {
|
||||
s1.executeUpdate(createInventoryTable);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Inventory table exists");
|
||||
}
|
||||
try {
|
||||
s1.executeUpdate(createInventoryRow);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Product row exists");
|
||||
}
|
||||
s1.close();
|
||||
String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )";
|
||||
Statement s2 = orderConnection.createStatement();
|
||||
try {
|
||||
s2.executeUpdate(createOrderTable);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Orders table exists");
|
||||
}
|
||||
s2.close();
|
||||
inventoryConnection.close();
|
||||
orderConnection.close();
|
||||
}
|
||||
|
||||
private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception {
|
||||
|
||||
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||
Statement s1 = inventoryConnection.createStatement();
|
||||
String q1 = "select balance from Inventory where productId='" + productId + "'";
|
||||
ResultSet rs1 = s1.executeQuery(q1);
|
||||
if (rs1 == null || !rs1.next())
|
||||
throw new Exception("Product not found: " + productId);
|
||||
long balance = rs1.getLong(1);
|
||||
inventoryConnection.close();
|
||||
return balance;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.baeldung.atomikos.spring.jpa;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.atomikos.spring.jpa.config.Config;
|
||||
import com.baeldung.atomikos.spring.jpa.inventory.Inventory;
|
||||
import com.baeldung.atomikos.spring.jpa.inventory.InventoryConfig;
|
||||
import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository;
|
||||
import com.baeldung.atomikos.spring.jpa.order.OrderConfig;
|
||||
import com.baeldung.atomikos.spring.jpa.order.OrderRepository;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { Config.class, InventoryConfig.class, OrderConfig.class })
|
||||
public class ApplicationUnitTest {
|
||||
|
||||
private static String productId = UUID.randomUUID()
|
||||
.toString();
|
||||
|
||||
@Autowired
|
||||
Application application;
|
||||
|
||||
@Autowired
|
||||
InventoryRepository inventoryRepository;
|
||||
|
||||
@Autowired
|
||||
OrderRepository orderRepository;
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPlaceOrderSuccess() throws Exception {
|
||||
int amount = 1;
|
||||
long initialBalance = getBalance(inventoryRepository, productId);
|
||||
application.placeOrder(productId, amount);
|
||||
long finalBalance = getBalance(inventoryRepository, productId);
|
||||
assertEquals(initialBalance - amount, finalBalance);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testPlaceOrderFailure() throws Exception {
|
||||
int amount = 10;
|
||||
long initialBalance = getBalance(inventoryRepository, productId);
|
||||
try {
|
||||
application.placeOrder(productId, amount);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
long finalBalance = getBalance(inventoryRepository, productId);
|
||||
assertEquals(initialBalance, finalBalance);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws SQLException {
|
||||
|
||||
Inventory inventory = new Inventory();
|
||||
inventory.setProductId(productId);
|
||||
inventory.setBalance(new Long(10000));
|
||||
inventoryRepository.save(inventory);
|
||||
|
||||
}
|
||||
|
||||
private static long getBalance(InventoryRepository inventoryRepository, String productId) throws Exception {
|
||||
|
||||
return inventoryRepository.findOne(productId)
|
||||
.getBalance();
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -7,12 +7,6 @@
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
1
atomikos/src/test/resources/transactions.properties
Normal file
1
atomikos/src/test/resources/transactions.properties
Normal file
@ -0,0 +1 @@
|
||||
com.atomikos.icatch.file=logs
|
56
aws-app-sync/pom.xml
Normal file
56
aws-app-sync/pom.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.6.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>aws-app-sync</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>aws-app-sync</name>
|
||||
|
||||
<description>Spring Boot using AWS App Sync</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
public class AppSyncClientHelper {
|
||||
|
||||
static String apiUrl = "https://m4i3b6icrrb7livfbypfspiifi.appsync-api.us-east-2.amazonaws.com";
|
||||
static String apiKey = "da2-bm4rpatkkrc5jfyhvvq7itjeke";
|
||||
static String API_KEY_HEADER = "x-api-key";
|
||||
|
||||
public static WebClient.ResponseSpec getResponseBodySpec(Map<String, Object> requestBody) {
|
||||
return WebClient
|
||||
.builder()
|
||||
.baseUrl(apiUrl)
|
||||
.defaultHeader(API_KEY_HEADER, apiKey)
|
||||
.defaultHeader("Content-Type", "application/json")
|
||||
.build()
|
||||
.method(HttpMethod.POST)
|
||||
.uri("/graphql")
|
||||
.body(BodyInserters.fromValue(requestBody))
|
||||
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
|
||||
.acceptCharset(StandardCharsets.UTF_8)
|
||||
.retrieve();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AwsAppSyncApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AwsAppSyncApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
class AwsAppSyncApplicationTests {
|
||||
|
||||
@Test
|
||||
void givenGraphQuery_whenListEvents_thenReturnAllEvents() {
|
||||
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("query", "query ListEvents {"
|
||||
+ " listEvents {"
|
||||
+ " items {"
|
||||
+ " id"
|
||||
+ " name"
|
||||
+ " where"
|
||||
+ " when"
|
||||
+ " description"
|
||||
+ " }"
|
||||
+ " }"
|
||||
+ "}");
|
||||
requestBody.put("variables", "");
|
||||
requestBody.put("operationName", "ListEvents");
|
||||
|
||||
String bodyString = AppSyncClientHelper.getResponseBodySpec(requestBody)
|
||||
.bodyToMono(String.class).block();
|
||||
|
||||
assertNotNull(bodyString);
|
||||
assertTrue(bodyString.contains("My First Event"));
|
||||
assertTrue(bodyString.contains("where"));
|
||||
assertTrue(bodyString.contains("when"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenGraphAdd_whenMutation_thenReturnIdNameDesc() {
|
||||
|
||||
String queryString = "mutation add {"
|
||||
+ " createEvent("
|
||||
+ " name:\"My added GraphQL event\""
|
||||
+ " where:\"Day 2\""
|
||||
+ " when:\"Saturday night\""
|
||||
+ " description:\"Studying GraphQL\""
|
||||
+ " ){"
|
||||
+ " id"
|
||||
+ " name"
|
||||
+ " description"
|
||||
+ " }"
|
||||
+ "}";
|
||||
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("query", queryString);
|
||||
requestBody.put("variables", "");
|
||||
requestBody.put("operationName", "add");
|
||||
|
||||
WebClient.ResponseSpec response = AppSyncClientHelper.getResponseBodySpec(requestBody);
|
||||
|
||||
String bodyString = response.bodyToMono(String.class).block();
|
||||
|
||||
assertNotNull(bodyString);
|
||||
assertTrue(bodyString.contains("My added GraphQL event"));
|
||||
assertFalse(bodyString.contains("where"));
|
||||
assertFalse(bodyString.contains("when"));
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Building Java Applications with Bazel](https://www.baeldung.com/bazel-build-tool)
|
@ -1,7 +1,18 @@
|
||||
## CAS
|
||||
|
||||
This module contains articles about the Central Authentication Service (CAS)
|
||||
This module contains articles about the Central Authentication Service (CAS).
|
||||
|
||||
The module consists of 2 submodules:
|
||||
1. `cas-server` - it requires JDK11 and uses the Gradle War Overlay style to ease setup and deployment. To start the server, simply run:
|
||||
|
||||
`./gradlew run
|
||||
-Dorg.gradle.java.home=$JAVA11_HOME
|
||||
-Pargs="-Dcas.standalone.configurationDirectory=/cas-server/src/main/resources/etc/cas/config"`
|
||||
|
||||
The server starts at https://localhost:8443. `casuser`/`Mellon` are the username and password for logging in.
|
||||
|
||||
2. `cas-secured-app` - A Maven based Springboot Application
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [CAS SSO With Spring Security](baeldung.com/spring-security-cas-sso)
|
||||
- [CAS SSO With Spring Security](https://www.baeldung.com/spring-security-cas-sso)
|
@ -1,146 +0,0 @@
|
||||
CAS Overlay Template [](https://travis-ci.org/apereo/cas-overlay-template)
|
||||
=======================
|
||||
|
||||
Generic CAS WAR overlay to exercise the latest versions of CAS. This overlay could be freely used as a starting template for local CAS war overlays.
|
||||
|
||||
# Versions
|
||||
|
||||
- CAS `6.1.x`
|
||||
- JDK `11`
|
||||
|
||||
# Overview
|
||||
|
||||
To build the project, use:
|
||||
|
||||
```bash
|
||||
# Use --refresh-dependencies to force-update SNAPSHOT versions
|
||||
./gradlew[.bat] clean build
|
||||
```
|
||||
|
||||
To see what commands are available to the build script, run:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] tasks
|
||||
```
|
||||
|
||||
To launch into the CAS command-line shell:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] downloadShell runShell
|
||||
```
|
||||
|
||||
To fetch and overlay a CAS resource or view, use:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] getResource -PresourceName=[resource-name]
|
||||
```
|
||||
|
||||
To list all available CAS views and templates:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] listTemplateViews
|
||||
```
|
||||
|
||||
To unzip and explode the CAS web application file and the internal resources jar:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] explodeWar
|
||||
```
|
||||
|
||||
# Configuration
|
||||
|
||||
- The `etc` directory contains the configuration files and directories that need to be copied to `/etc/cas/config`.
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] copyCasConfiguration
|
||||
```
|
||||
|
||||
- The specifics of the build are controlled using the `gradle.properties` file.
|
||||
|
||||
## Adding Modules
|
||||
|
||||
CAS modules may be specified under the `dependencies` block of the [Gradle build script](build.gradle):
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
compile "org.apereo.cas:cas-server-some-module:${project.casVersion}"
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
To collect the list of all project modules and dependencies:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] allDependencies
|
||||
```
|
||||
|
||||
### Clear Gradle Cache
|
||||
|
||||
If you need to, on Linux/Unix systems, you can delete all the existing artifacts (artifacts and metadata) Gradle has downloaded using:
|
||||
|
||||
```bash
|
||||
# Only do this when absolutely necessary
|
||||
rm -rf $HOME/.gradle/caches/
|
||||
```
|
||||
|
||||
Same strategy applies to Windows too, provided you switch `$HOME` to its equivalent in the above command.
|
||||
|
||||
# Deployment
|
||||
|
||||
- Create a keystore file `thekeystore` under `/etc/cas`. Use the password `changeit` for both the keystore and the key/certificate entries. This can either be done using the JDK's `keytool` utility or via the following command:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] createKeystore
|
||||
```
|
||||
|
||||
- Ensure the keystore is loaded up with keys and certificates of the server.
|
||||
|
||||
On a successful deployment via the following methods, CAS will be available at:
|
||||
|
||||
* `https://cas.server.name:8443/cas`
|
||||
|
||||
## Executable WAR
|
||||
|
||||
Run the CAS web application as an executable WAR:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] run
|
||||
```
|
||||
|
||||
Debug the CAS web application as an executable WAR:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] debug
|
||||
```
|
||||
|
||||
Run the CAS web application as a *standalone* executable WAR:
|
||||
|
||||
```bash
|
||||
./gradlew[.bat] clean executable
|
||||
```
|
||||
|
||||
## External
|
||||
|
||||
Deploy the binary web application file `cas.war` after a successful build to a servlet container of choice.
|
||||
|
||||
## Docker
|
||||
|
||||
The following strategies outline how to build and deploy CAS Docker images.
|
||||
|
||||
### Jib
|
||||
|
||||
The overlay embraces the [Jib Gradle Plugin](https://github.com/GoogleContainerTools/jib) to provide easy-to-use out-of-the-box tooling for building CAS docker images. Jib is an open-source Java containerizer from Google that lets Java developers build containers using the tools they know. It is a container image builder that handles all the steps of packaging your application into a container image. It does not require you to write a Dockerfile or have Docker installed, and it is directly integrated into the overlay.
|
||||
|
||||
```bash
|
||||
./gradlew build jibDockerBuild
|
||||
```
|
||||
|
||||
### Dockerfile
|
||||
|
||||
You can also use the native Docker tooling and the provided `Dockerfile` to build and run CAS.
|
||||
|
||||
```bash
|
||||
chmod +x *.sh
|
||||
./docker-build.sh
|
||||
./docker-run.sh
|
||||
```
|
40
core-groovy-2/determine-datatype/pom.xml
Normal file
40
core-groovy-2/determine-datatype/pom.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.groovy</groupId>
|
||||
<artifactId>determine-datatype</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmaven</groupId>
|
||||
<artifactId>groovy-maven-plugin</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>2.0.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.junit/junit5-engine -->
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit5-engine</artifactId>
|
||||
<version>5.0.0-ALPHA</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,14 @@
|
||||
package com.baeldung.groovy.determine.datatype
|
||||
|
||||
class Person {
|
||||
|
||||
private int ageAsInt
|
||||
private Double ageAsDouble
|
||||
private String ageAsString
|
||||
|
||||
Person() {}
|
||||
Person(int ageAsInt) { this.ageAsInt = ageAsInt}
|
||||
Person(Double ageAsDouble) { this.ageAsDouble = ageAsDouble}
|
||||
Person(String ageAsString) { this.ageAsString = ageAsString}
|
||||
}
|
||||
class Student extends Person {}
|
@ -0,0 +1,55 @@
|
||||
package com.baeldung.groovy.determine.datatype;
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test;
|
||||
|
||||
public class PersonTest {
|
||||
|
||||
@Test
|
||||
public void givenWhenParameterTypeIsInteger_thenReturnTrue() {
|
||||
Person personObj = new Person(10)
|
||||
Assert.assertTrue(personObj.ageAsInt instanceof Integer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWhenParameterTypeIsDouble_thenReturnTrue() {
|
||||
Person personObj = new Person(10.0)
|
||||
Assert.assertTrue((personObj.ageAsDouble).getClass() == Double)
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWhenParameterTypeIsString_thenReturnTrue() {
|
||||
Person personObj = new Person("10 years")
|
||||
Assert.assertTrue(personObj.ageAsString.class == String)
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenClassName_WhenParameterIsInteger_thenReturnTrue() {
|
||||
Assert.assertTrue(Person.class.getDeclaredField('ageAsInt').type == int.class)
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWhenObjectIsInstanceOfType_thenReturnTrue() {
|
||||
Person personObj = new Person()
|
||||
Assert.assertTrue(personObj instanceof Person)
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWhenInstanceIsOfSubtype_thenReturnTrue() {
|
||||
Student studentObj = new Student()
|
||||
Assert.assertTrue(studentObj in Person)
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGroovyList_WhenFindClassName_thenReturnTrue() {
|
||||
def ageList = ['ageAsString','ageAsDouble', 10]
|
||||
Assert.assertTrue(ageList.class == ArrayList)
|
||||
Assert.assertTrue(ageList.getClass() == ArrayList)
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGrooyMap_WhenFindClassName_thenReturnTrue() {
|
||||
def ageMap = [ageAsString: '10 years', ageAsDouble: 10.0]
|
||||
Assert.assertFalse(ageMap.class == LinkedHashMap)
|
||||
}
|
||||
}
|
@ -12,4 +12,5 @@ This module contains articles about core Groovy concepts
|
||||
- [Closures in Groovy](https://www.baeldung.com/groovy-closures)
|
||||
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
||||
- [[More -->]](/core-groovy-2)
|
||||
- [Convert String to Integer in Groovy](https://www.baeldung.com/groovy-convert-string-to-integer)
|
||||
- [[More -->]](/core-groovy-2)
|
||||
|
@ -0,0 +1,110 @@
|
||||
package com.baeldung.stringtoint
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import java.text.DecimalFormat
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
import static org.junit.Assert.assertNull
|
||||
|
||||
class ConvertStringToInt {
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingAsInteger_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
def invalidString = "123a"
|
||||
Integer expectedInteger = 123
|
||||
Integer integerNum = stringNum as Integer
|
||||
def intNum = invalidString?.isInteger() ? invalidString as Integer : null
|
||||
|
||||
assertNull(null, intNum)
|
||||
assertEquals(integerNum, expectedInteger)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingAsInt_thenConvertToInt() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
int intNum = stringNum as int
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingToInteger_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
int intNum = stringNum.toInteger()
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingParseInt_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
int intNum = Integer.parseInt(stringNum)
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingValueOf_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
int intNum = Integer.valueOf(stringNum)
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingIntValue_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
int intNum = new Integer(stringNum).intValue()
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingNewInteger_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
int intNum = new Integer(stringNum)
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingDecimalFormat_thenConvertToInteger() {
|
||||
def stringNum = "123"
|
||||
int expectedInt = 123
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#")
|
||||
int intNum = decimalFormat.parse(stringNum).intValue()
|
||||
|
||||
assertEquals(intNum, expectedInt)
|
||||
}
|
||||
|
||||
@Test(expected = NumberFormatException.class)
|
||||
void givenInvalidString_whenUsingAs_thenThrowNumberFormatException() {
|
||||
def invalidString = "123a"
|
||||
invalidString as Integer
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
void givenNullString_whenUsingToInteger_thenThrowNullPointerException() {
|
||||
def invalidString = null
|
||||
invalidString.toInteger()
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenUsingIsInteger_thenCheckIfCorrectValue() {
|
||||
def invalidString = "123a"
|
||||
def validString = "123"
|
||||
def invalidNum = invalidString?.isInteger() ? invalidString as Integer : false
|
||||
def correctNum = validString?.isInteger() ? validString as Integer : false
|
||||
|
||||
assertEquals(false, invalidNum)
|
||||
assertEquals(123, correctNum)
|
||||
}
|
||||
}
|
@ -7,3 +7,4 @@ This module contains articles about Java 14.
|
||||
- [Guide to the @Serial Annotation in Java 14](https://www.baeldung.com/java-14-serial-annotation)
|
||||
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
||||
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
||||
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
||||
|
@ -0,0 +1,56 @@
|
||||
package com.baeldung.java14.npe;
|
||||
|
||||
public class HelpfulNullPointerException {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Employee employee = null;
|
||||
employee.getName();
|
||||
}
|
||||
|
||||
public String getEmployeeEmailAddress(Employee employee) {
|
||||
String emailAddress = employee.getPersonalDetails().getEmailAddress().toLowerCase();
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
static class Employee {
|
||||
String name;
|
||||
PersonalDetails personalDetails;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public PersonalDetails getPersonalDetails() {
|
||||
return personalDetails;
|
||||
}
|
||||
|
||||
public void setPersonalDetails(PersonalDetails personalDetails) {
|
||||
this.personalDetails = personalDetails;
|
||||
}
|
||||
}
|
||||
|
||||
static class PersonalDetails {
|
||||
String emailAddress;
|
||||
String phone;
|
||||
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.java14.record;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public record Person (String name, String address) {
|
||||
|
||||
public static String UNKWOWN_ADDRESS = "Unknown";
|
||||
public static String UNNAMED = "Unnamed";
|
||||
|
||||
public Person {
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(address);
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this(name, UNKWOWN_ADDRESS);
|
||||
}
|
||||
|
||||
public static Person unnamed(String address) {
|
||||
return new Person(UNNAMED, address);
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.baeldung.java14.foreign.api;
|
||||
|
||||
import jdk.incubator.foreign.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class ForeignMemoryUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenAValueIsSet_thenAccessTheValue() {
|
||||
long value = 10;
|
||||
MemoryAddress memoryAddress =
|
||||
MemorySegment.allocateNative(8).baseAddress();
|
||||
VarHandle varHandle = MemoryHandles.varHandle(long.class,
|
||||
ByteOrder.nativeOrder());
|
||||
varHandle.set(memoryAddress, value);
|
||||
assertThat(varHandle.get(memoryAddress), is(value));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMultipleValuesAreSet_thenAccessAll() {
|
||||
VarHandle varHandle = MemoryHandles.varHandle(int.class,
|
||||
ByteOrder.nativeOrder());
|
||||
|
||||
try(MemorySegment memorySegment =
|
||||
MemorySegment.allocateNative(100)) {
|
||||
MemoryAddress base = memorySegment.baseAddress();
|
||||
for(int i=0; i<25; i++) {
|
||||
varHandle.set(base.addOffset((i*4)), i);
|
||||
}
|
||||
for(int i=0; i<25; i++) {
|
||||
assertThat(varHandle.get(base.addOffset((i*4))), is(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetValuesWithMemoryLayout_thenTheyCanBeRetrieved() {
|
||||
SequenceLayout sequenceLayout =
|
||||
MemoryLayout.ofSequence(25,
|
||||
MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder()));
|
||||
VarHandle varHandle =
|
||||
sequenceLayout.varHandle(long.class,
|
||||
MemoryLayout.PathElement.sequenceElement());
|
||||
|
||||
try(MemorySegment memorySegment =
|
||||
MemorySegment.allocateNative(sequenceLayout)) {
|
||||
MemoryAddress base = memorySegment.baseAddress();
|
||||
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||
varHandle.set(base, i, i);
|
||||
}
|
||||
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||
assertThat(varHandle.get(base, i), is(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSlicingMemorySegment_thenTheyCanBeAccessedIndividually() {
|
||||
MemoryAddress memoryAddress =
|
||||
MemorySegment.allocateNative(12).baseAddress();
|
||||
MemoryAddress memoryAddress1 =
|
||||
memoryAddress.segment().asSlice(0,4).baseAddress();
|
||||
MemoryAddress memoryAddress2 =
|
||||
memoryAddress.segment().asSlice(4,4).baseAddress();
|
||||
MemoryAddress memoryAddress3 =
|
||||
memoryAddress.segment().asSlice(8,4).baseAddress();
|
||||
|
||||
VarHandle intHandle =
|
||||
MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
|
||||
intHandle.set(memoryAddress1, Integer.MIN_VALUE);
|
||||
intHandle.set(memoryAddress2, 0);
|
||||
intHandle.set(memoryAddress3, Integer.MAX_VALUE);
|
||||
|
||||
assertThat(intHandle.get(memoryAddress1), is(Integer.MIN_VALUE));
|
||||
assertThat(intHandle.get(memoryAddress2), is(0));
|
||||
assertThat(intHandle.get(memoryAddress3), is(Integer.MAX_VALUE));
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.baeldung.java14.npe;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.baeldung.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.Employee;
|
||||
import static com.baeldung.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.PersonalDetails;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class HelpfulNullPointerExceptionUnitTest {
|
||||
|
||||
@Test (expected = NullPointerException.class)
|
||||
public void givenAnEmptyPersonalDetails_whenEmailAddressIsAccessed_thenThrowNPE() {
|
||||
var helpfulNPE = new HelpfulNullPointerException();
|
||||
|
||||
var employee = new Employee();
|
||||
employee.setName("Eduard");
|
||||
employee.setPersonalDetails(new PersonalDetails());
|
||||
helpfulNPE.getEmployeeEmailAddress(employee);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCompletePersonalDetails_whenEmailAddressIsAccessed_thenSuccess() {
|
||||
var helpfulNPE = new HelpfulNullPointerException();
|
||||
var emailAddress = "eduard@gmx.com";
|
||||
|
||||
var employee = new Employee();
|
||||
employee.setName("Eduard");
|
||||
|
||||
var personalDetails = new PersonalDetails();
|
||||
personalDetails.setEmailAddress(emailAddress.toUpperCase());
|
||||
personalDetails.setPhone("1234");
|
||||
employee.setPersonalDetails(personalDetails);
|
||||
|
||||
assertThat(helpfulNPE.getEmployeeEmailAddress(employee)).isEqualTo(emailAddress);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package com.baeldung.java14.record;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PersonTest {
|
||||
|
||||
@Test
|
||||
public void givenSameNameAndAddress_whenEquals_thenPersonsEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person(name, address);
|
||||
Person person2 = new Person(name, address);
|
||||
|
||||
assertTrue(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentObject_whenEquals_thenNotEqual() {
|
||||
|
||||
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||
|
||||
assertFalse(person.equals(new Object()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentName_whenEquals_thenPersonsNotEqual() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person("Jane Doe", address);
|
||||
Person person2 = new Person("John Doe", address);
|
||||
|
||||
assertFalse(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentAddress_whenEquals_thenPersonsNotEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person1 = new Person(name, "100 Linda Ln.");
|
||||
Person person2 = new Person(name, "200 London Ave.");
|
||||
|
||||
assertFalse(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSameNameAndAddress_whenHashCode_thenPersonsEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person(name, address);
|
||||
Person person2 = new Person(name, address);
|
||||
|
||||
assertEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentObject_whenHashCode_thenNotEqual() {
|
||||
|
||||
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||
|
||||
assertNotEquals(person.hashCode(), new Object().hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentName_whenHashCode_thenPersonsNotEqual() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person("Jane Doe", address);
|
||||
Person person2 = new Person("John Doe", address);
|
||||
|
||||
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentAddress_whenHashCode_thenPersonsNotEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person1 = new Person(name, "100 Linda Ln.");
|
||||
Person person2 = new Person(name, "200 London Ave.");
|
||||
|
||||
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = new Person(name, address);
|
||||
|
||||
assertEquals(name, person.name());
|
||||
assertEquals(address, person.address());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidNameAndAddress_whenToString_thenCorrectStringReturned() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = new Person(name, address);
|
||||
|
||||
assertEquals("Person[name=" + name + ", address=" + address + "]", person.toString());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenNullName_whenConstruct_thenErrorThrown() {
|
||||
new Person(null, "100 Linda Ln.");
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenNullAddress_whenConstruct_thenErrorThrown() {
|
||||
new Person("John Doe", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnknownAddress_whenConstructing_thenAddressPopulated() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person = new Person(name);
|
||||
|
||||
assertEquals(name, person.name());
|
||||
assertEquals(Person.UNKWOWN_ADDRESS, person.address());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnnamed_whenConstructingThroughFactory_thenNamePopulated() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = Person.unnamed(address);
|
||||
|
||||
assertEquals(Person.UNNAMED, person.name());
|
||||
assertEquals(address, person.address());
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ This module contains articles about Java 8 core features
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)
|
||||
- [Run a Java Application from the Command Line](https://www.baeldung.com/java-run-jar-with-arguments)
|
||||
- [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit)
|
||||
- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface)
|
||||
|
5
core-java-modules/core-java-8-datetime-2/README.md
Normal file
5
core-java-modules/core-java-8-datetime-2/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Generating Random Dates in Java](https://www.baeldung.com/java-random-dates)
|
||||
- [Creating a LocalDate with Values in Java](https://www.baeldung.com/java-creating-localdate-with-values)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1)
|
@ -4,9 +4,9 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-datetime-java8</artifactId>
|
||||
<artifactId>core-java-8-datetime</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<name>core-java-datetime-java8</name>
|
||||
<name>core-java-8-datetime</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
@ -64,8 +64,8 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.9</maven.compiler.source>
|
||||
<maven.compiler.target>1.9</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<joda-time.version>2.10</joda-time.version>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
@ -11,31 +11,31 @@ public class LocalDateExampleUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingOfMethod_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getCustomDateOne(2020, 1, 8));
|
||||
assertEquals("2020-01-08", date.getCustomDateOne(2020, 1, 8).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValuesWithMonthEnum_whenUsingOfMethod_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getCustomDateTwo(2020, Month.JANUARY, 8));
|
||||
assertEquals("2020-01-08", date.getCustomDateTwo(2020, Month.JANUARY, 8).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingEpochDay_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromEpochDay(18269));
|
||||
assertEquals("2020-01-08", date.getDateFromEpochDay(18269).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingYearDay_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromYearAndDayOfYear(2020, 8));
|
||||
assertEquals("2020-01-08", date.getDateFromYearAndDayOfYear(2020, 8).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingParse_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromString("2020-01-08"));
|
||||
assertEquals("2020-01-08", date.getDateFromString("2020-01-08").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValuesWithFormatter_whenUsingParse_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromStringAndFormatter("8-Jan-2020", "d-MMM-yyyy"));
|
||||
assertEquals("2020-01-08", date.getDateFromStringAndFormatter("8-Jan-2020", "d-MMM-yyyy").toString());
|
||||
}
|
||||
}
|
@ -13,4 +13,4 @@ This module contains articles about the Date and Time API introduced with Java 8
|
||||
- [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end)
|
||||
- [Set the Time Zone of a Date in Java](https://www.baeldung.com/java-set-date-time-zone)
|
||||
- [Comparing Dates in Java](https://www.baeldung.com/java-comparing-dates)
|
||||
- [Generating Random Dates in Java](https://www.baeldung.com/java-random-dates)
|
||||
- [[Next -->]](/core-java-modules/core-java-datetime-java8-2)
|
@ -4,9 +4,9 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-datetime-java8</artifactId>
|
||||
<artifactId>core-java-8-datetime</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<name>core-java-datetime-java8</name>
|
||||
<name>core-java-8-datetime</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
@ -64,8 +64,8 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.9</maven.compiler.source>
|
||||
<maven.compiler.target>1.9</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<joda-time.version>2.10</joda-time.version>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user