Merge remote-tracking branch 'eugenp/master'
This commit is contained in:
commit
da77f09e88
@ -3,7 +3,8 @@ language: java
|
||||
before_install:
|
||||
- echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc
|
||||
|
||||
install: travis_wait 60 mvn -q test -fae
|
||||
install: skip
|
||||
script: travis_wait 60 mvn -q test -fae
|
||||
|
||||
sudo: required
|
||||
|
||||
|
@ -39,6 +39,12 @@
|
||||
<artifactId>jgrapht-core</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,111 @@
|
||||
package com.baeldung.algorithms.kthlargest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class FindKthLargest {
|
||||
|
||||
public int findKthLargestBySorting(Integer[] arr, int k) {
|
||||
Arrays.sort(arr);
|
||||
int targetIndex = arr.length - k;
|
||||
return arr[targetIndex];
|
||||
}
|
||||
|
||||
public int findKthLargestBySortingDesc(Integer[] arr, int k) {
|
||||
Arrays.sort(arr, Collections.reverseOrder());
|
||||
return arr[k - 1];
|
||||
}
|
||||
|
||||
public int findKthElementByQuickSelect(Integer[] arr, int left, int right, int k) {
|
||||
if (k >= 0 && k <= right - left + 1) {
|
||||
int pos = partition(arr, left, right);
|
||||
if (pos - left == k) {
|
||||
return arr[pos];
|
||||
}
|
||||
if (pos - left > k) {
|
||||
return findKthElementByQuickSelect(arr, left, pos - 1, k);
|
||||
}
|
||||
return findKthElementByQuickSelect(arr, pos + 1, right, k - pos + left - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int findKthElementByQuickSelectWithIterativePartition(Integer[] arr, int left, int right, int k) {
|
||||
if (k >= 0 && k <= right - left + 1) {
|
||||
int pos = partitionIterative(arr, left, right);
|
||||
if (pos - left == k) {
|
||||
return arr[pos];
|
||||
}
|
||||
if (pos - left > k) {
|
||||
return findKthElementByQuickSelectWithIterativePartition(arr, left, pos - 1, k);
|
||||
}
|
||||
return findKthElementByQuickSelectWithIterativePartition(arr, pos + 1, right, k - pos + left - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int partition(Integer[] arr, int left, int right) {
|
||||
int pivot = arr[right];
|
||||
Integer[] leftArr;
|
||||
Integer[] rightArr;
|
||||
|
||||
leftArr = IntStream.range(left, right)
|
||||
.filter(i -> arr[i] < pivot)
|
||||
.map(i -> arr[i])
|
||||
.boxed()
|
||||
.toArray(Integer[]::new);
|
||||
|
||||
rightArr = IntStream.range(left, right)
|
||||
.filter(i -> arr[i] > pivot)
|
||||
.map(i -> arr[i])
|
||||
.boxed()
|
||||
.toArray(Integer[]::new);
|
||||
|
||||
int leftArraySize = leftArr.length;
|
||||
System.arraycopy(leftArr, 0, arr, left, leftArraySize);
|
||||
arr[leftArraySize + left] = pivot;
|
||||
System.arraycopy(rightArr, 0, arr, left + leftArraySize + 1, rightArr.length);
|
||||
|
||||
return left + leftArraySize;
|
||||
}
|
||||
|
||||
private int partitionIterative(Integer[] arr, int left, int right) {
|
||||
int pivot = arr[right], i = left;
|
||||
for (int j = left; j <= right - 1; j++) {
|
||||
if (arr[j] <= pivot) {
|
||||
swap(arr, i, j);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
swap(arr, i, right);
|
||||
return i;
|
||||
}
|
||||
|
||||
public int findKthElementByRandomizedQuickSelect(Integer[] arr, int left, int right, int k) {
|
||||
if (k >= 0 && k <= right - left + 1) {
|
||||
int pos = randomPartition(arr, left, right);
|
||||
if (pos - left == k) {
|
||||
return arr[pos];
|
||||
}
|
||||
if (pos - left > k) {
|
||||
return findKthElementByRandomizedQuickSelect(arr, left, pos - 1, k);
|
||||
}
|
||||
return findKthElementByRandomizedQuickSelect(arr, pos + 1, right, k - pos + left - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int randomPartition(Integer arr[], int left, int right) {
|
||||
int n = right - left + 1;
|
||||
int pivot = (int) (Math.random()) % n;
|
||||
swap(arr, left + pivot, right);
|
||||
return partition(arr, left, right);
|
||||
}
|
||||
|
||||
private void swap(Integer[] arr, int n1, int n2) {
|
||||
int temp = arr[n2];
|
||||
arr[n2] = arr[n1];
|
||||
arr[n1] = temp;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.baeldung.algorithms.kthlargest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class FindKthLargestUnitTest {
|
||||
|
||||
private FindKthLargest findKthLargest;
|
||||
private Integer[] arr = { 3, 7, 1, 2, 8, 10, 4, 5, 6, 9 };
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
findKthLargest = new FindKthLargest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenFindKthLargestBySorting_thenGetResult() {
|
||||
int k = 3;
|
||||
assertThat(findKthLargest.findKthLargestBySorting(arr, k)).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenFindKthLargestBySortingDesc_thenGetResult() {
|
||||
int k = 3;
|
||||
assertThat(findKthLargest.findKthLargestBySortingDesc(arr, k)).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenFindKthLargestByQuickSelect_thenGetResult() {
|
||||
int k = 3;
|
||||
int kthLargest = arr.length - k;
|
||||
assertThat(findKthLargest.findKthElementByQuickSelect(arr, 0, arr.length - 1, kthLargest)).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenFindKthElementByQuickSelectIterative_thenGetResult() {
|
||||
int k = 3;
|
||||
int kthLargest = arr.length - k;
|
||||
assertThat(findKthLargest.findKthElementByQuickSelectWithIterativePartition(arr, 0, arr.length - 1, kthLargest)).isEqualTo(8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenFindKthSmallestByQuickSelect_thenGetResult() {
|
||||
int k = 3;
|
||||
assertThat(findKthLargest.findKthElementByQuickSelect(arr, 0, arr.length - 1, k - 1)).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenFindKthLargestByRandomizedQuickSelect_thenGetResult() {
|
||||
int k = 3;
|
||||
int kthLargest = arr.length - k;
|
||||
assertThat(findKthLargest.findKthElementByRandomizedQuickSelect(arr, 0, arr.length - 1, kthLargest)).isEqualTo(8);
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.streamApi;
|
||||
package com.baeldung.stream;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
@ -16,7 +16,7 @@ public class StreamApi {
|
||||
}
|
||||
|
||||
public static String getLastElementUsingSkip(List<String> valueList) {
|
||||
long count = valueList.stream().count();
|
||||
long count = (long) valueList.size();
|
||||
Stream<String> stream = valueList.stream();
|
||||
return stream.skip(count - 1).findFirst().orElse(null);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.baeldung.java8;
|
||||
|
||||
import com.baeldung.streamApi.Product;
|
||||
import com.baeldung.stream.Product;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -6,6 +6,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@ -65,7 +66,9 @@ public class PrimitiveStreamsUnitTest {
|
||||
@Test
|
||||
public void givenAnArrayWhenSumIsCalledThenTheCorrectSumIsReturned() {
|
||||
|
||||
int sum = Arrays.asList(33,45).stream().mapToInt(a -> a).sum();
|
||||
int sum = Stream.of(33,45)
|
||||
.mapToInt(i -> i)
|
||||
.sum();
|
||||
|
||||
assertEquals(78, sum);
|
||||
}
|
||||
|
@ -131,4 +131,5 @@
|
||||
- [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array)
|
||||
- [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class)
|
||||
- [A Guide to Java Initialization](http://www.baeldung.com/java-initialization)
|
||||
|
||||
- [Implementing a Binary Tree in Java](http://www.baeldung.com/java-binary-tree)
|
||||
- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random)
|
||||
|
@ -389,6 +389,16 @@
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.0.0-M1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
|
22
core-java/src/main/java/com/baeldung/javadoc/Person.java
Normal file
22
core-java/src/main/java/com/baeldung/javadoc/Person.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.baeldung.javadoc;
|
||||
|
||||
public class Person {
|
||||
/**
|
||||
* This is a first name
|
||||
*/
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
64
core-java/src/main/java/com/baeldung/javadoc/SuperHero.java
Normal file
64
core-java/src/main/java/com/baeldung/javadoc/SuperHero.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.baeldung.javadoc;
|
||||
|
||||
/**
|
||||
* Hero is the main entity we will be using to . . .
|
||||
* @author Captain America
|
||||
*
|
||||
*/
|
||||
public class SuperHero extends Person {
|
||||
|
||||
/**
|
||||
* The public name of a hero that is common knowledge
|
||||
*/
|
||||
private String heroName;
|
||||
private String uniquePower;
|
||||
private int health;
|
||||
private int defense;
|
||||
|
||||
/**
|
||||
* <p>This is a simple description of the method. . .
|
||||
* <a href="http://www.supermanisthegreatest.com">Superman!</a>
|
||||
* </p>
|
||||
* @param incomingDamage the amount of incoming damage
|
||||
* @return the amount of health hero has after attack
|
||||
* @see <a href="http://www.link_to_jira/HERO-402">HERO-402</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
public int successfullyAttacked(int incomingDamage, String damageType) {
|
||||
// do things
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getHeroName() {
|
||||
return heroName;
|
||||
}
|
||||
|
||||
public void setHeroName(String heroName) {
|
||||
this.heroName = heroName;
|
||||
}
|
||||
|
||||
public String getUniquePower() {
|
||||
return uniquePower;
|
||||
}
|
||||
|
||||
public void setUniquePower(String uniquePower) {
|
||||
this.uniquePower = uniquePower;
|
||||
}
|
||||
|
||||
public int getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public void setHealth(int health) {
|
||||
this.health = health;
|
||||
}
|
||||
|
||||
public int getDefense() {
|
||||
return defense;
|
||||
}
|
||||
|
||||
public void setDefense(int defense) {
|
||||
this.defense = defense;
|
||||
}
|
||||
|
||||
}
|
@ -16,7 +16,7 @@ public class EchoMultiServer {
|
||||
try {
|
||||
serverSocket = new ServerSocket(port);
|
||||
while (true)
|
||||
new EchoClientHandler(serverSocket.accept()).run();
|
||||
new EchoClientHandler(serverSocket.accept()).start();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.threadlocalrandom;
|
||||
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
public class ThreadLocalRandomBenchMarkRunner {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Options options = new OptionsBuilder().include(ThreadLocalRandomBenchMarker.class.getSimpleName())
|
||||
.threads(1)
|
||||
.forks(1)
|
||||
.shouldFailOnError(true)
|
||||
.shouldDoGC(true)
|
||||
.jvmArgs("-server")
|
||||
.build();
|
||||
|
||||
new Runner(options).run();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.baeldung.threadlocalrandom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 1)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class ThreadLocalRandomBenchMarker {
|
||||
|
||||
List<Callable<Integer>> randomCallables = new ArrayList<>();
|
||||
List<Callable<Integer>> threadLocalRandomCallables = new ArrayList<>();
|
||||
|
||||
@Setup(Level.Iteration)
|
||||
public void init() {
|
||||
Random random = new Random();
|
||||
randomCallables = new ArrayList<>();
|
||||
threadLocalRandomCallables = new ArrayList<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
randomCallables.add(() -> {
|
||||
return random.nextInt();
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
threadLocalRandomCallables.add(() -> {
|
||||
return ThreadLocalRandom.current()
|
||||
.nextInt();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void randomValuesUsingRandom() throws InterruptedException {
|
||||
ExecutorService executor = Executors.newWorkStealingPool();
|
||||
executor.invokeAll(randomCallables);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void randomValuesUsingThreadLocalRandom() throws InterruptedException {
|
||||
ExecutorService executor = Executors.newWorkStealingPool();
|
||||
executor.invokeAll(threadLocalRandomCallables);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
}
|
@ -4,3 +4,4 @@
|
||||
- [An Overview of Identifiers in Hibernate](http://www.baeldung.com/hibernate-identifiers)
|
||||
- [Hibernate – Mapping Date and Time](http://www.baeldung.com/hibernate-date-time)
|
||||
- [Hibernate Inheritance Mapping](http://www.baeldung.com/hibernate-inheritance)
|
||||
- [A Guide to Multitenancy in Hibernate 5](http://www.baeldung.com/hibernate-5-multitenancy)
|
||||
|
2
java-lite/README.md
Normal file
2
java-lite/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
### Relevant Articles:
|
||||
- [RESTFul CRUD application with JavaLite] ()
|
105
java-lite/pom.xml
Normal file
105
java-lite/pom.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.baeldung</groupId>
|
||||
<artifactId>java-lite</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<jetty.maven.plugin.version>9.3.4.RC1</jetty.maven.plugin.version>
|
||||
<activejdbc.version>1.4.13</activejdbc.version>
|
||||
<activeweb.version>1.15</activeweb.version>
|
||||
<mysql.connector.java.version>5.1.45</mysql.connector.java.version>
|
||||
<sun.tools.version>1.7.0</sun.tools.version>
|
||||
<jackson.version>1.8.2</jackson.version>
|
||||
<junit.version>4.11</junit.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>${jetty.maven.plugin.version}</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>activejdbc.log</name>
|
||||
<value></value>
|
||||
</systemProperty>
|
||||
<systemProperty>
|
||||
<name>active_reload</name>
|
||||
<value>true</value>
|
||||
</systemProperty>
|
||||
<systemProperty>
|
||||
<name>activeweb.log.request</name>
|
||||
<value>true</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.javalite</groupId>
|
||||
<artifactId>activejdbc-instrumentation</artifactId>
|
||||
<version>${activejdbc.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>instrument</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.javalite</groupId>
|
||||
<artifactId>activeweb</artifactId>
|
||||
<version>${activeweb.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.connector.java.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${sun.tools.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-lgpl</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-lgpl</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
9
java-lite/src/main/java/app/config/AppBootstrap.java
Normal file
9
java-lite/src/main/java/app/config/AppBootstrap.java
Normal file
@ -0,0 +1,9 @@
|
||||
package app.config;
|
||||
|
||||
import org.javalite.activeweb.AppContext;
|
||||
import org.javalite.activeweb.Bootstrap;
|
||||
|
||||
public class AppBootstrap extends Bootstrap {
|
||||
public void init(AppContext context) {
|
||||
}
|
||||
}
|
15
java-lite/src/main/java/app/config/AppControllerConfig.java
Normal file
15
java-lite/src/main/java/app/config/AppControllerConfig.java
Normal file
@ -0,0 +1,15 @@
|
||||
package app.config;
|
||||
|
||||
import app.controllers.ProductsController;
|
||||
import org.javalite.activeweb.AbstractControllerConfig;
|
||||
import org.javalite.activeweb.AppContext;
|
||||
import org.javalite.activeweb.controller_filters.DBConnectionFilter;
|
||||
import org.javalite.activeweb.controller_filters.TimingFilter;
|
||||
|
||||
public class AppControllerConfig extends AbstractControllerConfig {
|
||||
@Override
|
||||
public void init(AppContext appContext) {
|
||||
addGlobalFilters(new TimingFilter());
|
||||
add(new DBConnectionFilter()).to(ProductsController.class);
|
||||
}
|
||||
}
|
11
java-lite/src/main/java/app/config/DbConfig.java
Normal file
11
java-lite/src/main/java/app/config/DbConfig.java
Normal file
@ -0,0 +1,11 @@
|
||||
package app.config;
|
||||
|
||||
import org.javalite.activeweb.AbstractDBConfig;
|
||||
import org.javalite.activeweb.AppContext;
|
||||
|
||||
public class DbConfig extends AbstractDBConfig {
|
||||
@Override
|
||||
public void init(AppContext appContext) {
|
||||
this.configFile("/database.properties");
|
||||
}
|
||||
}
|
101
java-lite/src/main/java/app/controllers/ProductsController.java
Normal file
101
java-lite/src/main/java/app/controllers/ProductsController.java
Normal file
@ -0,0 +1,101 @@
|
||||
package app.controllers;
|
||||
|
||||
import app.models.Product;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.javalite.activeweb.AppController;
|
||||
import org.javalite.activeweb.annotations.RESTful;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@RESTful
|
||||
public class ProductsController extends AppController {
|
||||
|
||||
public void index() {
|
||||
try {
|
||||
view("products", Product.findAll());
|
||||
render().contentType("application/json");
|
||||
} catch (Exception e) {
|
||||
view("message", "There was an error.", "code", 200);
|
||||
render("message");
|
||||
}
|
||||
}
|
||||
|
||||
public void create() {
|
||||
try {
|
||||
Map payload = new ObjectMapper().readValue(getRequestString(), Map.class);
|
||||
Product p = new Product();
|
||||
p.fromMap(payload);
|
||||
p.saveIt();
|
||||
view("message", "Successfully saved product id " + p.get("id"), "code", 200);
|
||||
render("message");
|
||||
} catch (Exception e) {
|
||||
view("message", "There was an error.", "code", 200);
|
||||
render("message");
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
try {
|
||||
Map payload = new ObjectMapper().readValue(getRequestString(), Map.class);
|
||||
String id = getId();
|
||||
Product p = Product.findById(id);
|
||||
if (p == null) {
|
||||
view("message", "Product id " + id + " not found.", "code", 200);
|
||||
render("message");
|
||||
return;
|
||||
}
|
||||
p.fromMap(payload);
|
||||
p.saveIt();
|
||||
view("message", "Successfully updated product id " + id, "code", 200);
|
||||
render("message");
|
||||
} catch (Exception e) {
|
||||
view("message", "There was an error.", "code", 200);
|
||||
render("message");
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
try {
|
||||
String id = getId();
|
||||
Product p = Product.findById(id);
|
||||
if (p == null) {
|
||||
view("message", "Product id " + id + " not found.", "code", 200);
|
||||
render("message");
|
||||
return;
|
||||
}
|
||||
view("product", p);
|
||||
render("_product");
|
||||
} catch (Exception e) {
|
||||
view("message", "There was an error.", "code", 200);
|
||||
render("message");
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
try {
|
||||
String id = getId();
|
||||
Product p = Product.findById(id);
|
||||
if (p == null) {
|
||||
view("message", "Product id " + id + " not found.", "code", 200);
|
||||
render("message");
|
||||
return;
|
||||
}
|
||||
p.delete();
|
||||
view("message", "Successfully deleted product id " + id, "code", 200);
|
||||
render("message");
|
||||
} catch (Exception e) {
|
||||
view("message", "There was an error.", "code", 200);
|
||||
render("message");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getContentType() {
|
||||
return "application/json";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLayout() {
|
||||
return null;
|
||||
}
|
||||
}
|
7
java-lite/src/main/java/app/models/Product.java
Normal file
7
java-lite/src/main/java/app/models/Product.java
Normal file
@ -0,0 +1,7 @@
|
||||
package app.models;
|
||||
|
||||
import org.javalite.activejdbc.Model;
|
||||
|
||||
public class Product extends Model {
|
||||
|
||||
}
|
4
java-lite/src/main/resources/database.properties
Normal file
4
java-lite/src/main/resources/database.properties
Normal file
@ -0,0 +1,4 @@
|
||||
development.driver=com.mysql.jdbc.Driver
|
||||
development.username=user
|
||||
development.password=password
|
||||
development.url=jdbc:mysql://localhost/dbname
|
@ -0,0 +1 @@
|
||||
,
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"id" : ${product.id},
|
||||
"name" : "${product.name}"
|
||||
}
|
@ -0,0 +1 @@
|
||||
[<@render partial="product" collection=products spacer="comma"/>]
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"message" : "${message}",
|
||||
"code" : ${code}
|
||||
}
|
25
java-lite/src/main/webapp/WEB-INF/web.xml
Normal file
25
java-lite/src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
||||
|
||||
|
||||
<filter>
|
||||
<filter-name>dispatcher</filter-name>
|
||||
<filter-class>org.javalite.activeweb.RequestDispatcher</filter-class>
|
||||
<init-param>
|
||||
<param-name>exclusions</param-name>
|
||||
<param-value>css,images,js,ico</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>encoding</param-name>
|
||||
<param-value>UTF-8</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>dispatcher</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
</web-app>
|
25
java-lite/src/test/java/app/models/ProductTest.java
Normal file
25
java-lite/src/test/java/app/models/ProductTest.java
Normal file
@ -0,0 +1,25 @@
|
||||
package app.models;
|
||||
|
||||
import org.javalite.activejdbc.Base;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ProductTest {
|
||||
|
||||
//@Test
|
||||
public void givenSavedProduct_WhenFindFirst_ThenSavedProductIsReturned() {
|
||||
//Open DB connection
|
||||
Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/dbname", "user", "password");
|
||||
|
||||
//Create a product and save it
|
||||
Product toSaveProduct = new Product();
|
||||
toSaveProduct.set("name", "Bread");
|
||||
toSaveProduct.saveIt();
|
||||
|
||||
//Find product
|
||||
Product savedProduct = Product.findFirst("name = ?", "Bread");
|
||||
|
||||
Assert.assertEquals(toSaveProduct.get("name"), savedProduct.get("name"));
|
||||
}
|
||||
|
||||
}
|
2
persistence-modules/java-cockroachdb/README.md
Normal file
2
persistence-modules/java-cockroachdb/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
### Relevant Articles:
|
||||
- [Guide to CockroachDB in Java](http://www.baeldung.com/)
|
74
persistence-modules/java-cockroachdb/pom.xml
Normal file
74
persistence-modules/java-cockroachdb/pom.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?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/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>java-cockroachdb</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<postgresql.version>42.1.4</postgresql.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>Central</id>
|
||||
<name>Central</name>
|
||||
<url>http://repo1.maven.org/maven2/</url>
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.cockroachdb.domain;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class Article {
|
||||
|
||||
private UUID id;
|
||||
|
||||
private String title;
|
||||
|
||||
private String author;
|
||||
|
||||
public Article(UUID id, String title, String author) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
package com.baeldung.cockroachdb.repository;
|
||||
|
||||
import com.baeldung.cockroachdb.domain.Article;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Repository for the articles table related operations
|
||||
*/
|
||||
public class ArticleRepository {
|
||||
|
||||
private static final String TABLE_NAME = "articles";
|
||||
private Connection connection;
|
||||
|
||||
public ArticleRepository(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the articles table.
|
||||
*/
|
||||
public void createTable() throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME)
|
||||
.append("(id uuid PRIMARY KEY, ")
|
||||
.append("title string,")
|
||||
.append("author string)");
|
||||
|
||||
final String query = sb.toString();
|
||||
Statement stmt = connection.createStatement();
|
||||
stmt.execute(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the articles table adding a column
|
||||
*
|
||||
* @param columnName Column name of the additional column
|
||||
* @param columnType Column type of the additional column
|
||||
* @throws SQLException
|
||||
*/
|
||||
public void alterTable(String columnName, String columnType) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("ALTER TABLE ").append(TABLE_NAME)
|
||||
.append(" ADD ")
|
||||
.append(columnName)
|
||||
.append(" ")
|
||||
.append(columnType);
|
||||
|
||||
final String query = sb.toString();
|
||||
Statement stmt = connection.createStatement();
|
||||
stmt.execute(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new article in the articles table
|
||||
*
|
||||
* @param article New article to insert
|
||||
* @throws SQLException
|
||||
*/
|
||||
public void insertArticle(Article article) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME)
|
||||
.append("(id, title, author) ")
|
||||
.append("VALUES (?,?,?)");
|
||||
|
||||
final String query = sb.toString();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||
preparedStatement.setString(1, article.getId().toString());
|
||||
preparedStatement.setString(2, article.getTitle());
|
||||
preparedStatement.setString(3, article.getAuthor());
|
||||
preparedStatement.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select article by Title
|
||||
*
|
||||
* @param title title of the article to retrieve
|
||||
* @return article with the given title
|
||||
* @throws SQLException
|
||||
*/
|
||||
public Article selectByTitle(String title) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME)
|
||||
.append(" WHERE title = ?");
|
||||
|
||||
final String query = sb.toString();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||
preparedStatement.setString(1, title);
|
||||
|
||||
try (ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
List<Article> articles = new ArrayList<>();
|
||||
|
||||
while (rs.next()) {
|
||||
Article article = new Article(
|
||||
UUID.fromString(rs.getString("id")),
|
||||
rs.getString("title"),
|
||||
rs.getString("author")
|
||||
);
|
||||
articles.add(article);
|
||||
}
|
||||
return articles.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all the articles
|
||||
*
|
||||
* @return list of all articles
|
||||
* @throws SQLException
|
||||
*/
|
||||
public List<Article> selectAll() throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
|
||||
|
||||
final String query = sb.toString();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||
try (ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
List<Article> articles = new ArrayList<>();
|
||||
|
||||
while (rs.next()) {
|
||||
Article article = new Article(
|
||||
UUID.fromString(rs.getString("id")),
|
||||
rs.getString("title"),
|
||||
rs.getString("author")
|
||||
);
|
||||
articles.add(article);
|
||||
}
|
||||
return articles;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete article by title
|
||||
*
|
||||
* @param title title of the article to delete
|
||||
* @throws SQLException
|
||||
*/
|
||||
public void deleteArticleByTitle(String title) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("DELETE FROM ").append(TABLE_NAME)
|
||||
.append(" WHERE title = ?");
|
||||
|
||||
final String query = sb.toString();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||
preparedStatement.setString(1, title);
|
||||
preparedStatement.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all rows in the table
|
||||
*
|
||||
* @throws SQLException
|
||||
*/
|
||||
public void truncateTable() throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("TRUNCATE TABLE ").append(TABLE_NAME);
|
||||
|
||||
final String query = sb.toString();
|
||||
Statement stmt = connection.createStatement();
|
||||
stmt.execute(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete table
|
||||
*/
|
||||
public void deleteTable() throws SQLException {
|
||||
StringBuilder sb = new StringBuilder("DROP TABLE IF EXISTS ").append(TABLE_NAME);
|
||||
|
||||
final String query = sb.toString();
|
||||
Statement stmt = connection.createStatement();
|
||||
stmt.execute(query);
|
||||
}
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
package com.baeldung.cockroachdb;
|
||||
|
||||
import com.baeldung.cockroachdb.domain.Article;
|
||||
import com.baeldung.cockroachdb.repository.ArticleRepository;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.postgresql.util.PSQLException;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ArticleRepositoryIntegrationTest {
|
||||
|
||||
private static final String TABLE_NAME = "articles";
|
||||
|
||||
private Connection con;
|
||||
private ArticleRepository articleRepository;
|
||||
|
||||
@Before
|
||||
public void connect() throws Exception {
|
||||
Class.forName("org.postgresql.Driver");
|
||||
con = DriverManager.getConnection("jdbc:postgresql://localhost:26257/testdb", "user17", "qwerty");
|
||||
|
||||
articleRepository = new ArticleRepository(con);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreatingTable_thenCreatedCorrectly() throws Exception {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
PreparedStatement preparedStatement = con.prepareStatement("SHOW TABLES");
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
List<String> tables = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
tables.add(resultSet.getString("Table"));
|
||||
}
|
||||
|
||||
assertTrue(tables.stream().anyMatch(t -> t.equals(TABLE_NAME)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAlteringTheTable_thenColumnAddedCorrectly() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
String columnName = "creationdate";
|
||||
articleRepository.alterTable(columnName, "DATE");
|
||||
|
||||
String query = "SHOW COLUMNS FROM " + TABLE_NAME;
|
||||
PreparedStatement preparedStatement = con.prepareStatement(query);
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
List<String> columns = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
columns.add(resultSet.getString("Field"));
|
||||
}
|
||||
|
||||
assertTrue(columns.stream().anyMatch(c -> c.equals(columnName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInsertingNewArticle_thenArticleExists() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
String title = "Guide to CockroachDB in Java";
|
||||
String author = "baeldung";
|
||||
Article article = new Article(UUID.randomUUID(), title, author);
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
Article savedArticle = articleRepository.selectByTitle(title);
|
||||
assertEquals(article.getTitle(), savedArticle.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSelectingAllArticles_thenAllArticlesAreReturned() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
List<Article> savedArticles = articleRepository.selectAll();
|
||||
|
||||
assertEquals(2, savedArticles.size());
|
||||
assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
|
||||
assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeletingArticleByTtile_thenArticleIsDeleted() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
articleRepository.deleteArticleByTitle("A Guide to MongoDB with Java");
|
||||
|
||||
List<Article> savedArticles = articleRepository.selectAll();
|
||||
assertEquals(1, savedArticles.size());
|
||||
assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
|
||||
assertFalse(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
|
||||
}
|
||||
|
||||
@Test(expected = PSQLException.class)
|
||||
public void whenDeletingATable_thenExceptionIfAccessed() throws SQLException {
|
||||
articleRepository.createTable();
|
||||
articleRepository.deleteTable();
|
||||
|
||||
StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
|
||||
|
||||
final String query = sb.toString();
|
||||
PreparedStatement preparedStatement = con.prepareStatement(query);
|
||||
preparedStatement.executeQuery();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenTruncatingATable_thenEmptyTable() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
articleRepository.truncateTable();
|
||||
|
||||
List<Article> savedArticles = articleRepository.selectAll();
|
||||
assertEquals(0, savedArticles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInsertingTwoArticlesWithSamePrimaryKeyInASingleTransaction_thenRollback() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
try {
|
||||
con.setAutoCommit(false);
|
||||
|
||||
UUID articleId = UUID.randomUUID();
|
||||
|
||||
Article article = new Article(articleId, "Guide to CockroachDB in Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
article = new Article(articleId, "A Guide to MongoDB with Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
con.commit();
|
||||
} catch (Exception e) {
|
||||
con.rollback();
|
||||
} finally {
|
||||
con.setAutoCommit(true);
|
||||
}
|
||||
|
||||
List<Article> savedArticles = articleRepository.selectAll();
|
||||
assertEquals(0, savedArticles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInsertingTwoArticlesInASingleTransaction_thenInserted() throws SQLException {
|
||||
articleRepository.deleteTable();
|
||||
articleRepository.createTable();
|
||||
|
||||
try {
|
||||
con.setAutoCommit(false);
|
||||
|
||||
Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
|
||||
articleRepository.insertArticle(article);
|
||||
|
||||
con.commit();
|
||||
} catch (Exception e) {
|
||||
con.rollback();
|
||||
} finally {
|
||||
con.setAutoCommit(true);
|
||||
}
|
||||
|
||||
List<Article> savedArticles = articleRepository.selectAll();
|
||||
assertEquals(2, savedArticles.size());
|
||||
assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
|
||||
assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
|
||||
}
|
||||
|
||||
@After
|
||||
public void disconnect() throws SQLException {
|
||||
articleRepository = null;
|
||||
con.close();
|
||||
con = null;
|
||||
}
|
||||
}
|
@ -179,7 +179,7 @@
|
||||
|
||||
<properties>
|
||||
<!-- Spring -->
|
||||
<org.springframework.version>4.3.10.RELEASE</org.springframework.version>
|
||||
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
|
||||
|
||||
<org.springframework.data.version>1.10.6.RELEASE</org.springframework.data.version>
|
||||
|
||||
|
@ -10,8 +10,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
|
||||
import org.springframework.orm.hibernate5.HibernateTransactionManager;
|
||||
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
|
2
pom.xml
2
pom.xml
@ -86,6 +86,7 @@
|
||||
<module>jackson</module>
|
||||
<!-- <module>persistence-modules/java-cassandra</module> -->
|
||||
<module>vavr</module>
|
||||
<module>java-lite</module>
|
||||
<module>javax-servlets</module>
|
||||
<module>javaxval</module>
|
||||
<module>jaxb</module>
|
||||
@ -268,6 +269,7 @@
|
||||
<module>deeplearning4j</module>
|
||||
<module>lucene</module>
|
||||
<module>vraptor</module>
|
||||
<module>persistence-modules/java-cockroachdb</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
@ -2,7 +2,7 @@
|
||||
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>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<artifactId>spring-custom-aop</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-boot</name>
|
||||
|
@ -0,0 +1,39 @@
|
||||
package org.baeldung.endpoints;
|
||||
|
||||
public class EndpointDTO {
|
||||
private String id;
|
||||
private boolean enabled;
|
||||
private boolean sensitive;
|
||||
|
||||
public EndpointDTO(String id, boolean enabled, boolean sensitive) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.enabled = enabled;
|
||||
this.sensitive = sensitive;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isSensitive() {
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
public void setSensitive(boolean sensitive) {
|
||||
this.sensitive = sensitive;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.baeldung.endpoints;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
@ -8,16 +9,16 @@ import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ListEndpoints extends AbstractEndpoint<List<Endpoint>> {
|
||||
private List<Endpoint> endpoints;
|
||||
public class ListEndpoints extends AbstractEndpoint<List<EndpointDTO>> {
|
||||
private List<EndpointDTO> endpointDTOs;
|
||||
|
||||
@Autowired
|
||||
public ListEndpoints(List<Endpoint> endpoints) {
|
||||
super("listEndpoints");
|
||||
this.endpoints = endpoints;
|
||||
this.endpointDTOs = endpoints.stream().map(endpoint -> new EndpointDTO(endpoint.getId(), endpoint.isEnabled(), endpoint.isSensitive())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Endpoint> invoke() {
|
||||
return this.endpoints;
|
||||
public List<EndpointDTO> invoke() {
|
||||
return this.endpointDTOs;
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@ This is the code of a simple API for some CRUD operations build using Spring Boo
|
||||
- MongoDB
|
||||
|
||||
### Running
|
||||
|
||||
To build and start the server simply type
|
||||
|
||||
```bash
|
||||
@ -20,4 +19,8 @@ $ mvn spring-boot:run -Dserver.port=8989
|
||||
|
||||
Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080)
|
||||
|
||||
Enjoy it :)
|
||||
Enjoy it :)
|
||||
|
||||
### Relevant articles
|
||||
|
||||
- [Intro to Jenkins 2 and the Power of Pipelines](http://www.baeldung.com/jenkins-pipelines)
|
||||
|
@ -1,20 +0,0 @@
|
||||
package com.baeldung.vavr.future;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static String appendData(String initial) {
|
||||
return initial + "Baeldung!";
|
||||
}
|
||||
|
||||
public static int divideByZero(int num) {
|
||||
return num / 0;
|
||||
}
|
||||
|
||||
public static String getSubstringMinusOne(String s) {
|
||||
return s.substring(-1);
|
||||
}
|
||||
|
||||
public static String getSubstringMinusTwo(String s) {
|
||||
return s.substring(-2);
|
||||
}
|
||||
}
|
@ -1,119 +1,102 @@
|
||||
package com.baeldung.vavr.future;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import io.vavr.Tuple;
|
||||
import io.vavr.Tuple2;
|
||||
import io.vavr.concurrent.Future;
|
||||
import io.vavr.control.Option;
|
||||
import io.vavr.control.Try;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
public class FutureTest {
|
||||
|
||||
|
||||
private static final String error = "Failed to get underlying value.";
|
||||
private static final String HELLO = "Welcome to Baeldung!";
|
||||
|
||||
@Test
|
||||
public void whenChangeExecutorService_thenCorrect() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(
|
||||
Executors.newSingleThreadExecutor(),
|
||||
() -> Util.appendData(initialValue));
|
||||
Thread.sleep(20);
|
||||
String result = resultFuture.getOrElse(error);
|
||||
public void whenChangeExecutorService_thenCorrect() {
|
||||
String result = Future.of(newSingleThreadExecutor(), () -> HELLO)
|
||||
.getOrElse(error);
|
||||
|
||||
assertThat(result).isEqualTo("Welcome to Baeldung!");
|
||||
assertThat(result)
|
||||
.isEqualTo(HELLO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAppendData_thenCorrect1() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue));
|
||||
Thread.sleep(20);
|
||||
String result = resultFuture.getOrElse(new String(error));
|
||||
public void whenAppendData_thenCorrect1() {
|
||||
String result = Future.of(() -> HELLO)
|
||||
.getOrElse(error);
|
||||
|
||||
assertThat(result).isEqualTo("Welcome to Baeldung!");
|
||||
assertThat(result)
|
||||
.isEqualTo(HELLO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAppendData_thenCorrect2() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue));
|
||||
Thread.sleep(20);
|
||||
resultFuture.await();
|
||||
public void whenAppendData_thenCorrect2() {
|
||||
Future<String> resultFuture = Future.of(() -> HELLO)
|
||||
.await();
|
||||
|
||||
Option<Try<String>> futureOption = resultFuture.getValue();
|
||||
Try<String> futureTry = futureOption.get();
|
||||
String result = futureTry.getOrElse(error);
|
||||
String result = futureOption.get().getOrElse(error);
|
||||
|
||||
assertThat(result).isEqualTo("Welcome to Baeldung!");
|
||||
assertThat(result)
|
||||
.isEqualTo(HELLO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAppendData_thenSuccess() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue))
|
||||
public void whenAppendData_thenSuccess() {
|
||||
String result = Future.of(() -> HELLO)
|
||||
.onSuccess(finalResult -> System.out.println("Successfully Completed - Result: " + finalResult))
|
||||
.onFailure(finalResult -> System.out.println("Failed - Result: " + finalResult));
|
||||
Thread.sleep(20);
|
||||
String result = resultFuture.getOrElse(error);
|
||||
.onFailure(finalResult -> System.out.println("Failed - Result: " + finalResult))
|
||||
.getOrElse(error);
|
||||
|
||||
assertThat(result).isEqualTo("Welcome to Baeldung!");
|
||||
assertThat(result)
|
||||
.isEqualTo(HELLO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenChainingCallbacks_thenCorrect() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue))
|
||||
.andThen(finalResult -> System.out.println("Completed - 1: " + finalResult))
|
||||
.andThen(finalResult -> System.out.println("Completed - 2: " + finalResult));
|
||||
Thread.sleep(20);
|
||||
String result = resultFuture.getOrElse(error);
|
||||
|
||||
assertThat(result).isEqualTo("Welcome to Baeldung!");
|
||||
public void whenChainingCallbacks_thenCorrect() {
|
||||
Future.of(() -> HELLO)
|
||||
.andThen(r -> System.out.println("Completed - 1: " + r))
|
||||
.andThen(r -> System.out.println("Completed - 2: " + r));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCallAwait_thenCorrect() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue));
|
||||
Thread.sleep(20);
|
||||
resultFuture = resultFuture.await();
|
||||
String result = resultFuture.getOrElse(error);
|
||||
public void whenCallAwait_thenCorrect() {
|
||||
Future<String> resultFuture = Future.of(() -> HELLO)
|
||||
.await();
|
||||
String result = resultFuture.getValue().get().getOrElse(error);
|
||||
|
||||
assertThat(result).isEqualTo("Welcome to Baeldung!");
|
||||
assertThat(result)
|
||||
.isEqualTo(HELLO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDivideByZero_thenGetThrowable1() throws InterruptedException {
|
||||
Future<Integer> resultFuture = Future.of(() -> Util.divideByZero(10));
|
||||
Thread.sleep(20);
|
||||
Future<Throwable> throwableFuture = resultFuture.failed();
|
||||
Throwable throwable = throwableFuture.getOrElse(new Throwable());
|
||||
public void whenDivideByZero_thenGetThrowable1() {
|
||||
Future<Integer> resultFuture = Future.of(() -> 10 / 0);
|
||||
|
||||
assertThat(throwable.getMessage()).isEqualTo("/ by zero");
|
||||
assertThatThrownBy(resultFuture::get)
|
||||
.isInstanceOf(ArithmeticException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDivideByZero_thenGetThrowable2() throws InterruptedException {
|
||||
Future<Integer> resultFuture = Future.of(() -> Util.divideByZero(10));
|
||||
Thread.sleep(20);
|
||||
resultFuture.await();
|
||||
Option<Throwable> throwableOption = resultFuture.getCause();
|
||||
Throwable throwable = throwableOption.getOrElse(new Throwable());
|
||||
public void whenDivideByZero_thenGetThrowable2() {
|
||||
Future<Integer> resultFuture = Future.of(() -> 10 / 0)
|
||||
.await();
|
||||
|
||||
assertThat(throwable.getMessage()).isEqualTo("/ by zero");
|
||||
assertThat(resultFuture.getCause().get().getMessage())
|
||||
.isEqualTo("/ by zero");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDivideByZero_thenCorrect() throws InterruptedException {
|
||||
Future<Integer> resultFuture = Future.of(() -> Util.divideByZero(10));
|
||||
Thread.sleep(20);
|
||||
resultFuture.await();
|
||||
public void whenDivideByZero_thenCorrect() {
|
||||
Future<Integer> resultFuture = Future.of(() -> 10 / 0)
|
||||
.await();
|
||||
|
||||
assertThat(resultFuture.isCompleted()).isTrue();
|
||||
assertThat(resultFuture.isSuccess()).isFalse();
|
||||
@ -121,76 +104,70 @@ public class FutureTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAppendData_thenFutureNotEmpty() throws InterruptedException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue));
|
||||
Thread.sleep(20);
|
||||
resultFuture.await();
|
||||
public void whenAppendData_thenFutureNotEmpty() {
|
||||
Future<String> resultFuture = Future.of(() -> HELLO)
|
||||
.await();
|
||||
|
||||
assertThat(resultFuture.isEmpty()).isFalse();
|
||||
assertThat(resultFuture.isEmpty())
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCallZip_thenCorrect() throws InterruptedException {
|
||||
Future<Tuple2<String, Integer>> future = Future.of(() -> "John")
|
||||
.zip(Future.of(() -> new Integer(5)));
|
||||
Thread.sleep(20);
|
||||
future.await();
|
||||
public void whenCallZip_thenCorrect() {
|
||||
Future<String> f1 = Future.of(() -> "hello1");
|
||||
Future<String> f2 = Future.of(() -> "hello2");
|
||||
|
||||
assertThat(future.getOrElse(new Tuple2<String, Integer>(error, 0)))
|
||||
.isEqualTo(Tuple.of("John", new Integer(5)));
|
||||
assertThat(f1.zip(f2).get())
|
||||
.isEqualTo(Tuple.of("hello1", "hello2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertToCompletableFuture_thenCorrect() throws InterruptedException, ExecutionException {
|
||||
String initialValue = "Welcome to ";
|
||||
Future<String> resultFuture = Future.of(() -> Util.appendData(initialValue));
|
||||
Thread.sleep(20);
|
||||
CompletableFuture<String> convertedFuture = resultFuture.toCompletableFuture();
|
||||
CompletableFuture<String> convertedFuture = Future.of(() -> HELLO)
|
||||
.toCompletableFuture();
|
||||
|
||||
assertThat(convertedFuture.get()).isEqualTo("Welcome to Baeldung!");
|
||||
assertThat(convertedFuture.get())
|
||||
.isEqualTo(HELLO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCallMap_thenCorrect() throws InterruptedException {
|
||||
Future<String> futureResult = Future.of(() -> new StringBuilder("from Baeldung"))
|
||||
.map(a -> "Hello " + a);
|
||||
Thread.sleep(20);
|
||||
futureResult.await();
|
||||
public void whenCallMap_thenCorrect() {
|
||||
Future<String> futureResult = Future.of(() -> "from Baeldung")
|
||||
.map(a -> "Hello " + a)
|
||||
.await();
|
||||
|
||||
assertThat(futureResult.getOrElse(error)).isEqualTo("Hello from Baeldung");
|
||||
assertThat(futureResult.get())
|
||||
.isEqualTo("Hello from Baeldung");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFutureFails_thenGetErrorMessage() throws InterruptedException {
|
||||
Future<String> resultFuture = Future.of(() -> Util.getSubstringMinusOne("Hello"));
|
||||
Thread.sleep(20);
|
||||
Future<String> errorMessageFuture = resultFuture.recover(Throwable::getMessage);
|
||||
String errorMessage = errorMessageFuture.getOrElse(error);
|
||||
public void whenFutureFails_thenGetErrorMessage() {
|
||||
Future<String> future = Future.of(() -> "Hello".substring(-1))
|
||||
.recover(x -> "fallback value");
|
||||
|
||||
assertThat(errorMessage).isEqualTo("String index out of range: -1");
|
||||
assertThat(future.get())
|
||||
.isEqualTo("fallback value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFutureFails_thenGetAnotherFuture() throws InterruptedException {
|
||||
Future<String> resultFuture = Future.of(() -> Util.getSubstringMinusOne("Hello"));
|
||||
Thread.sleep(20);
|
||||
Future<String> errorMessageFuture = resultFuture.recoverWith(a -> Future.of(a::getMessage));
|
||||
String errorMessage = errorMessageFuture.getOrElse(error);
|
||||
public void whenFutureFails_thenGetAnotherFuture() {
|
||||
Future<String> future = Future.of(() -> "Hello".substring(-1))
|
||||
.recoverWith(x -> Future.of(() -> "fallback value"));
|
||||
|
||||
assertThat(errorMessage).isEqualTo("String index out of range: -1");
|
||||
assertThat(future.get())
|
||||
.isEqualTo("fallback value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBothFuturesFail_thenGetErrorMessage() throws InterruptedException {
|
||||
Future<String> future1 = Future.of(() -> Util.getSubstringMinusOne("Hello"));
|
||||
Future<String> future2 = Future.of(() -> Util.getSubstringMinusTwo("Hello"));
|
||||
Thread.sleep(20);
|
||||
Future<String> errorMessageFuture = future1.fallbackTo(future2);
|
||||
public void whenBothFuturesFail_thenGetErrorMessage() {
|
||||
Future<String> f1 = Future.of(() -> "Hello".substring(-1));
|
||||
Future<String> f2 = Future.of(() -> "Hello".substring(-2));
|
||||
|
||||
Future<String> errorMessageFuture = f1.fallbackTo(f2);
|
||||
Future<Throwable> errorMessage = errorMessageFuture.failed();
|
||||
|
||||
|
||||
assertThat(
|
||||
errorMessage.getOrElse(new Throwable()).getMessage())
|
||||
errorMessage.get().getMessage())
|
||||
.isEqualTo("String index out of range: -1");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user