Merge remote-tracking branch 'origin/master'

This commit is contained in:
slavisa-baeldung 2017-04-18 14:00:23 +01:00
commit 4b0fbb892f
111 changed files with 2310 additions and 921 deletions

View File

@ -0,0 +1,44 @@
<?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>com.baeldung</groupId>
<artifactId>apache-commons-math</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,20 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.complex.Complex;
import org.junit.Assert;
import org.junit.Test;
public class ComplexTests {
@Test
public void whenComplexPow_thenCorrect() {
Complex first = new Complex(1.0, 3.0);
Complex second = new Complex(2.0, 5.0);
Complex power = first.pow(second);
Assert.assertEquals(-0.007563724861696302, power.getReal(), 1e-7);
Assert.assertEquals(0.01786136835085382, power.getImaginary(), 1e-7);
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.fraction.Fraction;
import org.apache.commons.math3.fraction.FractionFormat;
import org.junit.Assert;
import org.junit.Test;
public class FractionTests {
@Test
public void whenFractionAdd_thenCorrect() {
Fraction lhs = new Fraction(1, 3);
Fraction rhs = new Fraction(2, 5);
Fraction sum = lhs.add(rhs);
Assert.assertEquals(11, sum.getNumerator());
Assert.assertEquals(15, sum.getDenominator());
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.geometry.euclidean.twod.Line;
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.junit.Assert;
import org.junit.Test;
public class GeometryTests {
@Test
public void whenLineIntersection_thenCorrect() {
Line l1 = new Line(new Vector2D(0, 0), new Vector2D(1, 1), 0);
Line l2 = new Line(new Vector2D(0, 1), new Vector2D(1, 1.5), 0);
Vector2D intersection = l1.intersection(l2);
Assert.assertEquals(2, intersection.getX(), 1e-7);
Assert.assertEquals(2, intersection.getY(), 1e-7);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.integration.SimpsonIntegrator;
import org.apache.commons.math3.analysis.integration.UnivariateIntegrator;
import org.junit.Assert;
import org.junit.Test;
public class IntegrationTests {
@Test
public void whenUnivariateIntegratorIntegrate_thenCorrect() {
final UnivariateFunction function = v -> v;
final UnivariateIntegrator integrator = new SimpsonIntegrator(1.0e-12, 1.0e-8, 1, 32);
final double i = integrator.integrate(100, function, 0, 10);
Assert.assertEquals(16 + 2d/3d, i, 1e-7);
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.linear.*;
import org.junit.Assert;
import org.junit.Test;
public class LinearAlgebraTests {
@Test
public void whenDecompositionSolverSolve_thenCorrect() {
RealMatrix a =
new Array2DRowRealMatrix(new double[][] { { 2, 3, -2 }, { -1, 7, 6 }, { 4, -3, -5 } },
false);
RealVector b = new ArrayRealVector(new double[] { 1, -2, 1 }, false);
DecompositionSolver solver = new LUDecomposition(a).getSolver();
RealVector solution = solver.solve(b);
Assert.assertEquals(-0.3698630137, solution.getEntry(0), 1e-7);
Assert.assertEquals(0.1780821918, solution.getEntry(1), 1e-7);
Assert.assertEquals(-0.602739726, solution.getEntry(2), 1e-7);
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.distribution.NormalDistribution;
import org.junit.Test;
public class ProbabilitiesTests {
@Test
public void whenNormalDistributionSample_thenSuccess() {
final NormalDistribution normalDistribution = new NormalDistribution(10, 3);
System.out.println(normalDistribution.sample());
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.solvers.BracketingNthOrderBrentSolver;
import org.apache.commons.math3.analysis.solvers.UnivariateSolver;
import org.junit.Assert;
import org.junit.Test;
public class RootFindingTests {
@Test
public void whenUnivariateSolverSolver_thenCorrect() {
final UnivariateFunction function = v -> Math.pow(v, 2) - 2;
UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 1.0e-8, 5);
double c = solver.solve(100, function, -10.0, 10.0, 0);
Assert.assertEquals(-Math.sqrt(2), c, 1e-7);
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.commons.math;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class StatisticsTests {
private double[] values;
private DescriptiveStatistics descriptiveStatistics;
@Before
public void setUp() {
values = new double[] {65, 51 , 16, 11 , 6519, 191 ,0 , 98, 19854, 1, 32};
descriptiveStatistics = new DescriptiveStatistics();
for(double v : values) {
descriptiveStatistics.addValue(v);
}
}
@Test
public void whenDescriptiveStatisticsGetMean_thenCorrect() {
Assert.assertEquals(2439.8181818181815, descriptiveStatistics.getMean(), 1e-7);
}
@Test
public void whenDescriptiveStatisticsGetMedian_thenCorrect() {
Assert.assertEquals(51, descriptiveStatistics.getPercentile(50), 1e-7);
}
@Test
public void whenDescriptiveStatisticsGetStandardDeviation_thenCorrect() {
Assert.assertEquals(6093.054649651221, descriptiveStatistics.getStandardDeviation(), 1e-7);
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,10 +7,13 @@
</encoder> </encoder>
</appender> </appender>
<!-- <logger name="org.springframework" level="WARN" /> --> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,23 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
<Pattern> </pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n </encoder>
</Pattern>
</layout>
</appender> </appender>
<logger name="com.baeldung.apache.velocity.service" level="debug" <logger name="org.springframework" level="WARN" />
additivity="false"> <logger name="org.springframework.transaction" level="WARN" />
<appender-ref ref="STDOUT" />
</logger>
<root level="error"> <!-- 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" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -70,11 +70,6 @@
<artifactId>spring-aop</artifactId> <artifactId>spring-aop</artifactId>
<version>4.3.4.RELEASE</version> <version>4.3.4.RELEASE</version>
</dependency> </dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -1,10 +0,0 @@
log4j.rootLogger=TRACE, stdout
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.logger.org.springframework.aop.interceptor.PerformanceMonitorInterceptor=TRACE, stdout
log4j.logger.com.baeldung.performancemonitor.MyPerformanceMonitorInterceptor=INFO, stdout

View File

@ -1,18 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg %n</pattern> <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</layout> </pattern>
</encoder>
</appender> </appender>
<logger name="com.baeldung.hazelcast" level="INFO" additivity="false"> <logger name="org.springframework" level="WARN" />
<appender-ref ref="STDOUT" /> <logger name="org.springframework.transaction" level="WARN" />
</logger>
<root level="DEBUG"> <!-- 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" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,10 +7,13 @@
</encoder> </encoder>
</appender> </appender>
<!-- <logger name="org.springframework" level="WARN" /> --> <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"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -91,4 +91,4 @@
- [Avoiding ConcurrentModificationException when iterating and removing](http://www.baeldung.com/avoiding-concurrentmodificationexception-when-iterating-and-removing) - [Avoiding ConcurrentModificationException when iterating and removing](http://www.baeldung.com/avoiding-concurrentmodificationexception-when-iterating-and-removing)
- [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list) - [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list)
- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list) - [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list)
- [An Introduction to ThreadLocal in Java](http://www.baeldung.com/java-threadlocal)

View File

@ -14,9 +14,9 @@ public class LogForgingDemo {
public static void main(String[] args) { public static void main(String[] args) {
LogForgingDemo demo = new LogForgingDemo(); LogForgingDemo demo = new LogForgingDemo();
demo.addLog(String.valueOf(300)); demo.addLog("300");
demo.addLog(String.valueOf(300 + "\n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully")); demo.addLog("300 \n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully");
demo.addLog(String.valueOf(encode(300 + "\n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully"))); demo.addLog(encode("300 \n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully"));
} }
public static String encode(String message) { public static String encode(String message) {

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,10 +7,13 @@
</encoder> </encoder>
</appender> </appender>
<!-- <logger name="org.springframework" level="WARN" /> --> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -0,0 +1,33 @@
package com.baeldung.unsafe;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
class CASCounter {
private final Unsafe unsafe;
private volatile long counter = 0;
private long offset;
private Unsafe getUnsafe() throws IllegalAccessException, NoSuchFieldException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
}
public CASCounter() throws Exception {
unsafe = getUnsafe();
offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("counter"));
}
public void increment() {
long before = counter;
while (!unsafe.compareAndSwapLong(this, offset, before, before + 1)) {
before = counter;
}
}
public long getCounter() {
return counter;
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.unsafe;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
class OffHeapArray {
private final static int BYTE = 1;
private long size;
private long address;
private Unsafe getUnsafe() throws IllegalAccessException, NoSuchFieldException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
}
public OffHeapArray(long size) throws NoSuchFieldException, IllegalAccessException {
this.size = size;
address = getUnsafe().allocateMemory(size * BYTE);
}
public void set(long i, byte value) throws NoSuchFieldException, IllegalAccessException {
getUnsafe().putByte(address + i * BYTE, value);
}
public int get(long idx) throws NoSuchFieldException, IllegalAccessException {
return getUnsafe().getByte(address + idx * BYTE);
}
public long size() {
return size;
}
public void freeMemory() throws NoSuchFieldException, IllegalAccessException {
getUnsafe().freeMemory(address);
}
}

View File

@ -0,0 +1,123 @@
package com.baeldung.unsafe;
import org.junit.Before;
import org.junit.Test;
import sun.misc.Unsafe;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals;
public class UnsafeTest {
private Unsafe unsafe;
@Before
public void setup() throws NoSuchFieldException, IllegalAccessException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = (Unsafe) f.get(null);
}
@Test
public void givenClass_whenInitializeIt_thenShouldHaveDifferentStateWhenUseUnsafe() throws IllegalAccessException, InstantiationException {
//when
InitializationOrdering o1 = new InitializationOrdering();
assertEquals(o1.getA(), 1);
//when
InitializationOrdering o3 = (InitializationOrdering) unsafe.allocateInstance(InitializationOrdering.class);
assertEquals(o3.getA(), 0);
}
@Test
public void givenPrivateMethod_whenUsingUnsafe_thenCanModifyPrivateField() throws NoSuchFieldException {
//given
SecretHolder secretHolder = new SecretHolder();
//when
Field f = secretHolder.getClass().getDeclaredField("SECRET_VALUE");
unsafe.putInt(secretHolder, unsafe.objectFieldOffset(f), 1);
//then
assertTrue(secretHolder.secretIsDisclosed());
}
@Test(expected = IOException.class)
public void givenUnsafeThrowException_whenThrowCheckedException_thenNotNeedToCatchIt() {
unsafe.throwException(new IOException());
}
@Test
public void givenArrayBiggerThatMaxInt_whenAllocateItOffHeapMemory_thenSuccess() throws NoSuchFieldException, IllegalAccessException {
//given
long SUPER_SIZE = (long) Integer.MAX_VALUE * 2;
OffHeapArray array = new OffHeapArray(SUPER_SIZE);
//when
int sum = 0;
for (int i = 0; i < 100; i++) {
array.set((long) Integer.MAX_VALUE + i, (byte) 3);
sum += array.get((long) Integer.MAX_VALUE + i);
}
long arraySize = array.size();
array.freeMemory();
//then
assertEquals(arraySize, SUPER_SIZE);
assertEquals(sum, 300);
}
@Test
public void givenUnsafeCompareAndSwap_whenUseIt_thenCounterYildCorrectLockFreeResults() throws Exception {
//given
int NUM_OF_THREADS = 1_000;
int NUM_OF_INCREMENTS = 10_000;
ExecutorService service = Executors.newFixedThreadPool(NUM_OF_THREADS);
CASCounter casCounter = new CASCounter();
//when
IntStream.rangeClosed(0, NUM_OF_THREADS - 1)
.forEach(i -> service.submit(() -> IntStream
.rangeClosed(0, NUM_OF_INCREMENTS - 1)
.forEach(j -> casCounter.increment())));
service.shutdown();
service.awaitTermination(1, TimeUnit.MINUTES);
//then
assertEquals(NUM_OF_INCREMENTS * NUM_OF_THREADS, casCounter.getCounter());
}
class InitializationOrdering {
private long a;
public InitializationOrdering() {
this.a = 1;
}
public long getA() {
return this.a;
}
}
class SecretHolder {
private int SECRET_VALUE = 0;
public boolean secretIsDisclosed() {
return SECRET_VALUE == 1;
}
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -8,10 +8,12 @@
</appender> </appender>
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="com.baeldung" level="DEBUG" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -8,10 +8,12 @@
</appender> </appender>
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="com.baeldung" level="DEBUG" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,18 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg %n</pattern> <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</layout> </pattern>
</encoder>
</appender> </appender>
<logger name="com.baeldung.hazelcast" level="INFO" additivity="false"> <logger name="org.springframework" level="WARN" />
<appender-ref ref="STDOUT" /> <logger name="org.springframework.transaction" level="WARN" />
</logger>
<root level="DEBUG"> <!-- 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" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,11 +7,13 @@
</encoder> </encoder>
</appender> </appender>
<logger name="org.apache.http" level="DEBUG" /> <logger name="org.springframework" level="WARN" />
<logger name="org.apache.http.wire" level="INFO" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,18 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg %n</pattern> <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</layout> </pattern>
</encoder>
</appender> </appender>
<logger name="com.baeldung.hazelcast" level="INFO" additivity="false"> <logger name="org.springframework" level="WARN" />
<appender-ref ref="STDOUT" /> <logger name="org.springframework.transaction" level="WARN" />
</logger>
<root level="DEBUG"> <!-- 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" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,8 +7,13 @@
</encoder> </encoder>
</appender> </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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -0,0 +1,143 @@
package com.baeldung.kotlin
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class GenericsTest {
@Test
fun givenParametrizeClass_whenInitializeItWithSpecificType_thenShouldBeParameterized() {
//given
val parameterizedClass = ParameterizedClass<String>("string-value")
//when
val res = parameterizedClass.getValue()
//then
assertTrue(res is String)
}
@Test
fun givenParametrizeClass_whenInitializeIt_thenShouldBeParameterizedByInferredType() {
//given
val parameterizedClass = ParameterizedClass("string-value")
//when
val res = parameterizedClass.getValue()
//then
assertTrue(res is String)
}
@Test
fun givenParameterizedProducerByOutKeyword_whenGetValue_thenCanAssignItToSuperType() {
//given
val parameterizedProducer = ParameterizedProducer("string")
//when
val ref: ParameterizedProducer<Any> = parameterizedProducer
//then
assertTrue(ref is ParameterizedProducer<Any>)
}
@Test
fun givenParameterizedConsumerByInKeyword_whenGetValue_thenCanAssignItToSubType() {
//given
val parameterizedConsumer = ParameterizedConsumer<Number>()
//when
val ref: ParameterizedConsumer<Double> = parameterizedConsumer
//then
assertTrue(ref is ParameterizedConsumer<Double>)
}
@Test
fun givenTypeProjections_whenOperateOnTwoList_thenCanAcceptListOfSubtypes() {
//given
val ints: Array<Int> = arrayOf(1, 2, 3)
val any: Array<Any?> = arrayOfNulls(3)
//when
copy(ints, any)
//then
assertEquals(any[0], 1)
assertEquals(any[1], 2)
assertEquals(any[2], 3)
}
fun copy(from: Array<out Any>, to: Array<Any?>) {
assert(from.size == to.size)
for (i in from.indices)
to[i] = from[i]
}
@Test
fun givenTypeProjection_whenHaveArrayOfIn_thenShouldAddElementsOfSubtypesToIt() {
//given
val objects: Array<Any?> = arrayOfNulls(1)
//when
fill(objects, 1)
//then
assertEquals(objects[0], 1)
}
fun fill(dest: Array<in Int>, value: Int) {
dest[0] = value
}
@Test
fun givenStartProjection_whenPassAnyType_thenCompile() {
//given
val array = arrayOf(1,2,3)
//then
printArray(array)
}
fun printArray(array: Array<*>) {
array.forEach { println(it) }
}
@Test
fun givenFunctionWithDefinedGenericConstraints_whenCallWithProperType_thenCompile(){
//given
val listOfInts = listOf(5,2,3,4,1)
//when
val sorted = sort(listOfInts)
//then
assertEquals(sorted, listOf(1,2,3,4,5))
}
fun <T: Comparable<T>> sort(list: List<T>): List<T>{
return list.sorted()
}
class ParameterizedClass<A>(private val value: A) {
fun getValue(): A {
return value
}
}
class ParameterizedProducer<out T>(private val value: T) {
fun get(): T {
return value
}
}
class ParameterizedConsumer<in T> {
fun toString(value: T): String {
return value.toString()
}
}
}

View File

@ -6,6 +6,7 @@
- [Introduction to Javatuples](http://www.baeldung.com/java-tuples) - [Introduction to Javatuples](http://www.baeldung.com/java-tuples)
- [Introduction to Javassist](http://www.baeldung.com/javassist) - [Introduction to Javassist](http://www.baeldung.com/javassist)
- [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) - [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded)
- [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink)
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -4,19 +4,16 @@ import com.baeldung.mybatis.model.Address;
import com.baeldung.mybatis.model.Person; import com.baeldung.mybatis.model.Person;
import org.apache.ibatis.annotations.*; import org.apache.ibatis.annotations.*;
public interface AddressMapper { public interface AddressMapper {
@Insert("Insert into address (streetAddress,personId) values(#{streetAddress},#{personId})") @Insert("Insert into address (streetAddress,personId) values(#{streetAddress},#{personId})")
@Options(useGeneratedKeys = true,flushCache=true ) @Options(useGeneratedKeys = true, flushCache = true)
public Integer saveAddress(Address address); public Integer saveAddress(Address address);
@Select("SELECT addressId, streetAddress FROM Address WHERE addressId = #{addressId}") @Select("SELECT addressId, streetAddress FROM Address WHERE addressId = #{addressId}")
@Results(value = { @Results(value = { @Result(property = "addressId", column = "addressId"),
@Result(property = "addressId", column = "addressId"),
@Result(property = "streetAddress", column = "streetAddress"), @Result(property = "streetAddress", column = "streetAddress"),
@Result(property = "person", column = "personId",javaType =Person.class,one=@One(select = "getPerson")) @Result(property = "person", column = "personId", javaType = Person.class, one = @One(select = "getPerson")) })
})
Address getAddresses(Integer addressID); Address getAddresses(Integer addressID);
@Select("SELECT personId FROM address WHERE addressId = #{addressId})") @Select("SELECT personId FROM address WHERE addressId = #{addressId})")

View File

@ -9,7 +9,6 @@ import org.apache.ibatis.mapping.StatementType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public interface PersonMapper { public interface PersonMapper {
@Insert("Insert into person(name) values (#{name})") @Insert("Insert into person(name) values (#{name})")
@ -25,11 +24,8 @@ public interface PersonMapper {
Person getPerson(Integer personId); Person getPerson(Integer personId);
@Select("Select personId,name from Person where personId=#{personId}") @Select("Select personId,name from Person where personId=#{personId}")
@Results(value ={ @Results(value = { @Result(property = "personId", column = "personId"), @Result(property = "name", column = "name"),
@Result(property = "personId", column = "personId"), @Result(property = "addresses", javaType = List.class, column = "personId", many = @Many(select = "getAddresses"))
@Result(property="name", column = "name"),
@Result(property = "addresses",javaType = List.class,column = "personId",
many=@Many(select = "getAddresses"))
}) })
public Person getPersonById(Integer personId); public Person getPersonById(Integer personId);
@ -39,13 +35,12 @@ public interface PersonMapper {
@Select("select * from Person ") @Select("select * from Person ")
@MapKey("personId") @MapKey("personId")
Map<Integer,Person> getAllPerson(); Map<Integer, Person> getAllPerson();
@SelectProvider(type=MyBatisUtil.class,method="getPersonByName") @SelectProvider(type = MyBatisUtil.class, method = "getPersonByName")
public Person getPersonByName(String name); public Person getPersonByName(String name);
@Select(value = "{ CALL getPersonByProc( #{personId, mode=IN, jdbcType=INTEGER})}")
@Select(value= "{ CALL getPersonByProc( #{personId, mode=IN, jdbcType=INTEGER})}")
@Options(statementType = StatementType.CALLABLE) @Options(statementType = StatementType.CALLABLE)
public Person getPersonByProc(Integer personId); public Person getPersonByProc(Integer personId);

View File

@ -1,6 +1,5 @@
package com.baeldung.mybatis.model; package com.baeldung.mybatis.model;
public class Address { public class Address {
private Integer addressId; private Integer addressId;
@ -18,10 +17,8 @@ public class Address {
this.personId = personId; this.personId = personId;
} }
public Address(String streetAddress) { public Address(String streetAddress) {
this.streetAddress =streetAddress; this.streetAddress = streetAddress;
} }
public Person getPerson() { public Person getPerson() {

View File

@ -3,7 +3,6 @@ package com.baeldung.mybatis.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Person { public class Person {
private Integer personId; private Integer personId;
@ -14,13 +13,13 @@ public class Person {
} }
public Person(Integer personId, String name) { public Person(Integer personId, String name) {
this.personId=personId; this.personId = personId;
this.name = name; this.name = name;
addresses = new ArrayList<Address>(); addresses = new ArrayList<Address>();
} }
public Person(String name) { public Person(String name) {
this.name=name; this.name = name;
} }
public Integer getPersonId() { public Integer getPersonId() {
@ -30,7 +29,8 @@ public class Person {
public String getName() { public String getName() {
return name; return name;
} }
public void addAddress(Address address){
public void addAddress(Address address) {
addresses.add(address); addresses.add(address);
} }

View File

@ -1,33 +1,50 @@
package com.baeldung.mybatis.utils; package com.baeldung.mybatis.utils;
import com.baeldung.mybatis.mapper.AddressMapper;
import com.baeldung.mybatis.mapper.PersonMapper;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.SQL; import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import javax.sql.DataSource;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
public class MyBatisUtil { public class MyBatisUtil {
public static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
public static final String URL = "jdbc:derby:testdb1;create=true";
public static final String USERNAME = "sa";
public static final String PASSWORD = "pass123";
private static SqlSessionFactory sqlSessionFactory; private static SqlSessionFactory sqlSessionFactory;
static {
String resource = "mybatis-config.xml"; public static SqlSessionFactory buildqlSessionFactory() {
InputStream inputStream; DataSource dataSource = new PooledDataSource(DRIVER, URL, USERNAME, PASSWORD);
try { Environment environment = new Environment("Development", new JdbcTransactionFactory(), dataSource);
inputStream = Resources.getResourceAsStream(resource); Configuration configuration = new Configuration(environment);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); configuration.addMapper(PersonMapper.class);
} catch (IOException e) { configuration.addMapper(AddressMapper.class);
e.printStackTrace(); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);
return factory;
} }
}
public static SqlSessionFactory getSqlSessionFactory(){ public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory; return sqlSessionFactory;
} }
public String getPersonByName(String name){ public String getPersonByName(String name) {
return new SQL(){{ return new SQL() {
{
SELECT("*"); SELECT("*");
FROM("person"); FROM("person");
WHERE("name like #{name} || '%'"); WHERE("name like #{name} || '%'");
}}.toString(); }
}.toString();
} }
} }

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="url" value="jdbc:derby:testdb1;create=true"/>
<property name="username" value="sa"/>
<property name="password" value="pass123"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.baeldung.mybatis.mapper.PersonMapper"/>
<mapper class="com.baeldung.mybatis.mapper.AddressMapper"/>
</mappers>
</configuration>

View File

@ -23,28 +23,23 @@ public class PersonMapperTest {
@Before @Before
public void setup() throws SQLException { public void setup() throws SQLException {
session = MyBatisUtil.getSqlSessionFactory().openSession(); session = MyBatisUtil.buildqlSessionFactory().openSession();
createTables(session); createTables(session);
} }
private void createTables(SqlSession session) throws SQLException { private void createTables(SqlSession session) throws SQLException {
String createPersonTable = "create table person (" String createPersonTable = "create table person (" + "personId integer not null generated always as"
+ "personId integer not null generated always as" + " identity (start with 1, increment by 1), " + "name varchar(30) not null, "
+ " identity (start with 1, increment by 1), "
+ "name varchar(30) not null, "
+ "constraint primary_key_person primary key (personId))"; + "constraint primary_key_person primary key (personId))";
String createAddressTable = "create table address (" String createAddressTable = "create table address (" + "addressId integer not null generated always as"
+ "addressId integer not null generated always as" + " identity (start with 1, increment by 1), " + "streetAddress varchar(300), personId integer, "
+ " identity (start with 1, increment by 1), "
+ "streetAddress varchar(300), personId integer, "
+ "constraint primary_key_address primary key (addressId))"; + "constraint primary_key_address primary key (addressId))";
String alterTable="ALTER TABLE " + String alterTable = "ALTER TABLE "
" address ADD CONSTRAINT fk_person FOREIGN KEY (personId) REFERENCES person (personId)"; + " address ADD CONSTRAINT fk_person FOREIGN KEY (personId) REFERENCES person (personId)";
session.getConnection().createStatement().execute(createPersonTable); session.getConnection().createStatement().execute(createPersonTable);
session.getConnection().createStatement().execute(createAddressTable); session.getConnection().createStatement().execute(createAddressTable);
@ -53,86 +48,87 @@ public class PersonMapperTest {
} }
@Test @Test
public void whenPersonAdressSaved_ThenPersonAddressCanBeQueried(){ public void whenPersonAdressSaved_ThenPersonAddressCanBeQueried() {
Person person=new Person("Baljeet S"); Person person = new Person("Baljeet S");
Address address = new Address("Pune"); Address address = new Address("Pune");
PersonMapper personMapper=session.getMapper(PersonMapper.class); PersonMapper personMapper = session.getMapper(PersonMapper.class);
Integer id =personMapper.save(person); Integer id = personMapper.save(person);
address.setPersonId(id); address.setPersonId(id);
AddressMapper addressMapper=session.getMapper(AddressMapper.class); AddressMapper addressMapper = session.getMapper(AddressMapper.class);
addressMapper.saveAddress(address); addressMapper.saveAddress(address);
Person returnedPerson= personMapper.getPersonById(id); Person returnedPerson = personMapper.getPersonById(id);
assertEquals("Baljeet S", returnedPerson.getName()); assertEquals("Baljeet S", returnedPerson.getName());
assertEquals("Pune", returnedPerson.getAddresses().get(0).getStreetAddress()); assertEquals("Pune", returnedPerson.getAddresses().get(0).getStreetAddress());
} }
@Test @Test
public void whenPersonSaved_ThenPersonCanBeQueried(){ public void whenPersonSaved_ThenPersonCanBeQueried() {
Person person=new Person("Baljeet S"); Person person = new Person("Baljeet S");
Address address = new Address("Pune"); Address address = new Address("Pune");
PersonMapper personMapper=session.getMapper(PersonMapper.class); PersonMapper personMapper = session.getMapper(PersonMapper.class);
Integer id =personMapper.save(person); Integer id = personMapper.save(person);
address.setPersonId(id); address.setPersonId(id);
AddressMapper addressMapper=session.getMapper(AddressMapper.class); AddressMapper addressMapper = session.getMapper(AddressMapper.class);
addressMapper.saveAddress(address); addressMapper.saveAddress(address);
Person returnedPerson= personMapper.getPerson(id); Person returnedPerson = personMapper.getPerson(id);
assertEquals("Baljeet S", returnedPerson.getName()); assertEquals("Baljeet S", returnedPerson.getName());
} }
@Test @Test
public void whenPersonUpdated_ThenPersonIsChanged(){ public void whenPersonUpdated_ThenPersonIsChanged() {
Person person=new Person("Baljeet S"); Person person = new Person("Baljeet S");
Address address = new Address("Pune"); Address address = new Address("Pune");
PersonMapper personMapper=session.getMapper(PersonMapper.class); PersonMapper personMapper = session.getMapper(PersonMapper.class);
Integer id =personMapper.save(person); Integer id = personMapper.save(person);
address.setPersonId(id); address.setPersonId(id);
AddressMapper addressMapper=session.getMapper(AddressMapper.class); AddressMapper addressMapper = session.getMapper(AddressMapper.class);
addressMapper.saveAddress(address); addressMapper.saveAddress(address);
personMapper.updatePerson(new Person(id,"Baljeet1")); personMapper.updatePerson(new Person(id, "Baljeet1"));
Person returnedPerson= personMapper.getPerson(id); Person returnedPerson = personMapper.getPerson(id);
assertEquals("Baljeet1", returnedPerson.getName()); assertEquals("Baljeet1", returnedPerson.getName());
} }
@Test @Test
public void whenPersoSaved_ThenMapIsReturned(){ public void whenPersoSaved_ThenMapIsReturned() {
Person person=new Person("Baljeet S"); Person person = new Person("Baljeet S");
Address address = new Address("Pune"); Address address = new Address("Pune");
PersonMapper personMapper=session.getMapper(PersonMapper.class); PersonMapper personMapper = session.getMapper(PersonMapper.class);
Integer id =personMapper.save(person); Integer id = personMapper.save(person);
address.setPersonId(id); address.setPersonId(id);
AddressMapper addressMapper=session.getMapper(AddressMapper.class); AddressMapper addressMapper = session.getMapper(AddressMapper.class);
addressMapper.saveAddress(address); addressMapper.saveAddress(address);
Map<Integer, Person> returnedPerson= personMapper.getAllPerson(); Map<Integer, Person> returnedPerson = personMapper.getAllPerson();
assertEquals(1, returnedPerson.size()); assertEquals(1, returnedPerson.size());
} }
@Test @Test
public void whenPersonSearched_ThenResultIsReturned(){ public void whenPersonSearched_ThenResultIsReturned() {
Person person=new Person("Baljeet S"); Person person = new Person("Baljeet S");
Address address = new Address("Pune"); Address address = new Address("Pune");
PersonMapper personMapper=session.getMapper(PersonMapper.class); PersonMapper personMapper = session.getMapper(PersonMapper.class);
Integer id =personMapper.save(person); Integer id = personMapper.save(person);
address.setPersonId(id); address.setPersonId(id);
AddressMapper addressMapper=session.getMapper(AddressMapper.class); AddressMapper addressMapper = session.getMapper(AddressMapper.class);
addressMapper.saveAddress(address); addressMapper.saveAddress(address);
Person returnedPerson= personMapper.getPersonByName("Baljeet S"); Person returnedPerson = personMapper.getPersonByName("Baljeet S");
assertEquals("Baljeet S", returnedPerson.getName()); assertEquals("Baljeet S", returnedPerson.getName());
} }
@Test @Test
public void whenAddressSearched_ThenResultIsReturned(){ public void whenAddressSearched_ThenResultIsReturned() {
Person person=new Person("Baljeet S"); Person person = new Person("Baljeet S");
Address address = new Address("Pune"); Address address = new Address("Pune");
PersonMapper personMapper=session.getMapper(PersonMapper.class); PersonMapper personMapper = session.getMapper(PersonMapper.class);
Integer id =personMapper.save(person); Integer id = personMapper.save(person);
address.setPersonId(id); address.setPersonId(id);
AddressMapper addressMapper=session.getMapper(AddressMapper.class); AddressMapper addressMapper = session.getMapper(AddressMapper.class);
Integer addressId=addressMapper.saveAddress(address); Integer addressId = addressMapper.saveAddress(address);
Address returnedAddress=addressMapper.getAddresses(addressId); Address returnedAddress = addressMapper.getAddresses(addressId);
assertEquals("Pune", returnedAddress.getStreetAddress()); assertEquals("Pune", returnedAddress.getStreetAddress());
} }

View File

@ -1,37 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p: %c - %m%n</Pattern> <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</layout> </pattern>
</encoder>
</appender> </appender>
<!-- Application Loggers --> <logger name="org.springframework" level="WARN" />
<logger name="de.slackspace.tutorials"> <logger name="org.springframework.transaction" level="WARN" />
<level value="debug" />
</logger>
<!-- Spring Loggers --> <!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.springframework.core"> <logger name="org.springframework.web.servlet.mvc" level="WARN" />
<level value="info" />
</logger>
<logger name="org.springframework.beans"> <root level="INFO">
<level value="info" /> <appender-ref ref="STDOUT" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<!-- Hibernate Loggers -->
<logger name="org.hibernate">
<level value="warn" />
</logger>
<root level="warn">
<appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>

View File

@ -60,14 +60,15 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>log4j</artifactId> <artifactId>logback-classic</artifactId>
<version>${log4j.version}</version> <version>${logback.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>slf4j-log4j12</artifactId> <artifactId>logback-core</artifactId>
<version>${slf4j.version}</version> <version>${logback.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -276,8 +277,9 @@
<javax.mail.version>1.4.7</javax.mail.version> <javax.mail.version>1.4.7</javax.mail.version>
<jetty.version>9.4.0.v20161208</jetty.version> <jetty.version>9.4.0.v20161208</jetty.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.7.21</slf4j.version> <slf4j.version>1.7.21</slf4j.version>
<logback.version>1.1.7</logback.version>
<commons-lang3.version>3.5</commons-lang3.version> <commons-lang3.version>3.5</commons-lang3.version>
<commons-logging.version>1.2</commons-logging.version> <commons-logging.version>1.2</commons-logging.version>

View File

@ -1,16 +0,0 @@
## Logger configure
datestamp=yyyy-MM-dd HH:mm:ss
log4j.rootLogger=TRACE, file, console
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.maxFileSize=1GB
log4j.appender.file.maxBackupIndex=5
log4j.appender.file.File=log/rest-assured.log
log4j.appender.file.threshold=TRACE
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{${datestamp}} %5p: [%c] - %m%n
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=INFO
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{${datestamp}} %5p\: [%c] - %m%n

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</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>
</configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,11 +7,13 @@
</encoder> </encoder>
</appender> </appender>
<logger name="org.apache.http" level="DEBUG" /> <logger name="org.springframework" level="WARN" />
<logger name="org.apache.http.wire" level="INFO" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,3 +1,19 @@
<configuration scan="true" scanPeriod="10 seconds"> <?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</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>
</configuration> </configuration>

View File

@ -1,3 +1,19 @@
<configuration scan="true" scanPeriod="10 seconds"> <?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</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>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -13,10 +13,7 @@
<!-- in order to debug some marshalling issues, this needs to be TRACE --> <!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.springframework.web.servlet.mvc" level="WARN" /> <logger name="org.springframework.web.servlet.mvc" level="WARN" />
<logger name="org.springframework.core.io.support" level="INFO" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -17,4 +17,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Guide to Internationalization in Spring Boot](http://www.baeldung.com/spring-boot-internationalization) - [Guide to Internationalization in Spring Boot](http://www.baeldung.com/spring-boot-internationalization)
- [Create a Custom FailureAnalyzer with Spring Boot](http://www.baeldung.com/spring-boot-failure-analyzer) - [Create a Custom FailureAnalyzer with Spring Boot](http://www.baeldung.com/spring-boot-failure-analyzer)
- [Configuring Separate Spring DataSource for Tests](http://www.baeldung.com/spring-testing-separate-data-source) - [Configuring Separate Spring DataSource for Tests](http://www.baeldung.com/spring-testing-separate-data-source)
- [Dynamic DTO Validation Config Retrieved from DB](http://www.baeldung.com/spring-dynamic-dto-validation)

View File

@ -1,16 +1,14 @@
package com.baeldung.dynamicvalidation; package com.baeldung.dynamicvalidation;
import java.util.regex.Pattern; import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository;
import com.baeldung.dynamicvalidation.model.ContactInfoExpression;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.thymeleaf.util.StringUtils; import org.thymeleaf.util.StringUtils;
import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository; import javax.validation.ConstraintValidator;
import com.baeldung.dynamicvalidation.model.ContactInfoExpression; import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class ContactInfoValidator implements ConstraintValidator<ContactInfo, String> { public class ContactInfoValidator implements ConstraintValidator<ContactInfo, String> {
@ -26,12 +24,15 @@ public class ContactInfoValidator implements ConstraintValidator<ContactInfo, St
@Override @Override
public boolean isValid(final String value, final ConstraintValidatorContext context) { public boolean isValid(final String value, final ConstraintValidatorContext context) {
if (!StringUtils.isEmptyOrWhitespace(expressionType)) { if (StringUtils.isEmptyOrWhitespace(expressionType)) {
final String pattern = expressionRepository.findOne(expressionType).map(ContactInfoExpression::getPattern).orElse("");
if (Pattern.matches(pattern, value))
return true;
}
return false; return false;
} }
return expressionRepository
.findOne(expressionType)
.map(ContactInfoExpression::getPattern)
.map(p -> Pattern.matches(p, value))
.orElse(false);
}
} }

View File

@ -0,0 +1,43 @@
package org.baeldung.boot.boottest;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;
@Entity
@Table(name = "person")
public class Employee {
public Employee() {
}
public Employee(String name) {
this.name = name;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Size(min = 3, max = 20)
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,21 @@
package org.baeldung.boot.boottest;
import java.util.List;
import java.util.Optional;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
@Transactional
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
public Optional<Employee> findByName(String name);
public Optional<Employee> findById(Long id);
public List<Employee> findAll();
}

View File

@ -0,0 +1,32 @@
package org.baeldung.boot.boottest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class EmployeeRestController {
@Autowired
EmployeeService employeeService;
@RequestMapping(value = "/employees", method = RequestMethod.POST)
public ResponseEntity<Employee> createEmployee(@RequestBody Employee employee) {
HttpStatus status = HttpStatus.CREATED;
Employee saved = employeeService.save(employee);
return new ResponseEntity<>(saved, status);
}
@RequestMapping(value = "/employees", method = RequestMethod.GET)
public List<Employee> getAllEmployees() {
return employeeService.getAllEmployees();
}
}

View File

@ -0,0 +1,17 @@
package org.baeldung.boot.boottest;
import java.util.List;
import java.util.Optional;
public interface EmployeeService {
public Optional<Employee> getEmployeeById(Long id);
public Optional<Employee> getEmployeeByName(String name);
public List<Employee> getAllEmployees();
public boolean exists(String email);
public Employee save(Employee employee);
}

View File

@ -0,0 +1,45 @@
package org.baeldung.boot.boottest;
import java.util.List;
import java.util.Optional;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
EmployeeRepository employeeRepository;
@Override
public Optional<Employee> getEmployeeById(Long id) {
return employeeRepository.findById(id);
}
@Override
public Optional<Employee> getEmployeeByName(String name) {
return employeeRepository.findByName(name);
}
@Override
public boolean exists(String name) {
if (employeeRepository.findByName(name) != null) {
return true;
}
return false;
}
@Override
public Employee save(Employee employee) {
return employeeRepository.save(employee);
}
@Override
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,8 +7,13 @@
</encoder> </encoder>
</appender> </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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -0,0 +1,78 @@
package org.baeldung.boot.boottest;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import org.baeldung.boot.boottest.Employee;
import org.baeldung.boot.boottest.EmployeeRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataJpaTest
public class EmployeeRepositoryTest {
@Autowired
TestEntityManager entityManager;
@Autowired
EmployeeRepository employeeRepository;
@Test
public void whenFindByName_thenReturnEmployee() {
Employee emp = new Employee("test");
entityManager.persistAndFlush(emp);
Optional<Employee> fromDb = employeeRepository.findByName(emp.getName());
assertThat(fromDb.get()
.getName()).isEqualTo(emp.getName());
}
@Test(expected = NoSuchElementException.class)
public void whenInvalidName_thenNoSuchElementException() {
Optional<Employee> fromDb = employeeRepository.findByName("doesNotExist");
fromDb.get();
}
@Test
public void whenFindById_thenReturnEmployee() {
Employee emp = new Employee("test");
entityManager.persistAndFlush(emp);
Optional<Employee> fromDb = employeeRepository.findById(emp.getId());
assertThat(fromDb.get()
.getName()).isEqualTo(emp.getName());
}
@Test(expected = NoSuchElementException.class)
public void whenInvalidId_thenNoSuchElementException() {
Optional<Employee> fromDb = employeeRepository.findById(-11L);
fromDb.get();
}
@Test
public void givenSetOfEmployees_whenFindAll_thenReturnAllEmployees() {
Employee alex = new Employee("alex");
Employee ron = new Employee("ron");
Employee bob = new Employee("bob");
entityManager.persist(alex);
entityManager.persist(bob);
entityManager.persist(ron);
entityManager.flush();
List<Employee> allEmployees = employeeRepository.findAll();
assertThat(allEmployees).hasSize(3)
.extracting(Employee::getName)
.containsOnly(alex.getName(), ron.getName(), bob.getName());
}
}

View File

@ -0,0 +1,78 @@
package org.baeldung.boot.boottest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.IOException;
import java.util.List;
import org.baeldung.boot.DemoApplication;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = DemoApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application-integrationtest.properties")
public class EmployeeRestControllerIntTest {
@Autowired
MockMvc mvc;
@Autowired
EmployeeRepository repository;
@After
public void resetDb() {
repository.deleteAll();
}
@Test
public void whenValidInput_thenCreateEmployee() throws IOException, Exception {
Employee bob = new Employee("bob");
mvc.perform(post("/api/employees").contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(bob)));
List<Employee> found = repository.findAll();
assertThat(found).extracting(Employee::getName)
.containsOnly("bob");
}
@Test
public void givenEmployees_whenGetEmployees_thenStatus200() throws Exception {
createTestEmployee("bob");
createTestEmployee("alex");
mvc.perform(get("/api/employees").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(greaterThanOrEqualTo(2))))
.andExpect(jsonPath("$[0].name", is("bob")))
.andExpect(jsonPath("$[1].name", is("alex")));
}
private void createTestEmployee(String name) {
Employee emp = new Employee(name);
repository.saveAndFlush(emp);
}
}

View File

@ -0,0 +1,78 @@
package org.baeldung.boot.boottest;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Arrays;
import java.util.List;
import org.baeldung.boot.boottest.Employee;
import org.baeldung.boot.boottest.EmployeeRestController;
import org.baeldung.boot.boottest.EmployeeService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@WebMvcTest(EmployeeRestController.class)
public class EmployeeRestControllerTest {
@Autowired
MockMvc mvc;
@MockBean
EmployeeService service;
@Before
public void setUp() throws Exception {
}
@Test
public void whenPostEmployee_thenCreateEmployee() throws Exception {
Employee alex = new Employee("alex");
given(service.save(Mockito.anyObject())).willReturn(alex);
mvc.perform(post("/api/employees").contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(alex)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name", is("alex")));
verify(service, VerificationModeFactory.times(1)).save(Mockito.anyObject());
reset(service);
}
@Test
public void givenEmployees_whenGetEmployees_thenReturnJsonArray() throws Exception {
Employee alex = new Employee("alex");
Employee john = new Employee("john");
Employee bob = new Employee("bob");
List<Employee> allEmployees = Arrays.asList(alex, john, bob);
given(service.getAllEmployees()).willReturn(allEmployees);
mvc.perform(get("/api/employees").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].name", is(alex.getName())))
.andExpect(jsonPath("$[1].name", is(john.getName())))
.andExpect(jsonPath("$[2].name", is(bob.getName())));
verify(service, VerificationModeFactory.times(1)).getAllEmployees();
reset(service);
}
}

View File

@ -0,0 +1,145 @@
package org.baeldung.boot.boottest;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import org.baeldung.boot.boottest.Employee;
import org.baeldung.boot.boottest.EmployeeRepository;
import org.baeldung.boot.boottest.EmployeeService;
import org.baeldung.boot.boottest.EmployeeServiceImpl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
public class EmployeeServiceImplTest {
@TestConfiguration
static class EmployeeServiceImplTestContextConfiguration {
@Bean
public EmployeeService employeeService() {
return new EmployeeServiceImpl();
}
}
@Autowired
EmployeeService employeeService;
@MockBean
EmployeeRepository employeeRepository;
@Before
public void setUp() {
Employee john = new Employee("john");
john.setId(11L);
Optional<Employee> emp = Optional.of(john);
Employee bob = new Employee("bob");
Employee alex = new Employee("alex");
List<Employee> allEmployees = Arrays.asList(john, bob, alex);
Mockito.when(employeeRepository.findByName(john.getName()))
.thenReturn(emp);
Mockito.when(employeeRepository.findByName("wrong_name"))
.thenReturn(Optional.empty());
Mockito.when(employeeRepository.findById(john.getId()))
.thenReturn(emp);
Mockito.when(employeeRepository.findAll())
.thenReturn(allEmployees);
Mockito.when(employeeRepository.findById(-99L))
.thenReturn(Optional.empty());
}
@Test
public void whenValidName_thenEmployeeShouldBeFound() {
Optional<Employee> fromDb = employeeService.getEmployeeByName("john");
assertThat(fromDb.get()
.getName()).isEqualTo("john");
verifyFindByNameIsCalledOnce("john");
}
@Test(expected = NoSuchElementException.class)
public void whenInValidName_thenEmployeeShouldNotBeFound() {
Optional<Employee> fromDb = employeeService.getEmployeeByName("wrong_name");
fromDb.get();
verifyFindByNameIsCalledOnce("wrong_name");
}
@Test
public void whenValidName_thenEmployeeShouldExist() {
boolean doesEmployeeExist = employeeService.exists("john");
assertThat(doesEmployeeExist).isEqualTo(true);
verifyFindByNameIsCalledOnce("john");
}
@Test
public void whenNonExistingName_thenEmployeeShouldNotExist() {
boolean doesEmployeeExist = employeeService.exists("some_name");
assertThat(doesEmployeeExist).isEqualTo(false);
verifyFindByNameIsCalledOnce("some_name");
}
@Test
public void whenValidI_thendEmployeeShouldBeFound() {
Optional<Employee> fromDb = employeeService.getEmployeeById(11L);
assertThat(fromDb.get()
.getName()).isEqualTo("john");
verifyFindByIdIsCalledOnce();
}
@Test(expected = NoSuchElementException.class)
public void whenInValidId_thenEmployeeShouldNotBeFound() {
Optional<Employee> fromDb = employeeService.getEmployeeById(-99L);
verifyFindByIdIsCalledOnce();
fromDb.get();
}
@Test
public void given3Employees_whengetAll_thenReturn3Records() {
Employee alex = new Employee("alex");
Employee john = new Employee("john");
Employee bob = new Employee("bob");
List<Employee> allEmployees = employeeService.getAllEmployees();
verifyFindAllEmployeesIsCalledOnce();
assertThat(allEmployees).hasSize(3)
.extracting(Employee::getName)
.contains(alex.getName(), john.getName(), bob.getName());
}
private void verifyFindByNameIsCalledOnce(String name) {
Mockito.verify(employeeRepository, VerificationModeFactory.times(1))
.findByName(name);
Mockito.reset(employeeRepository);
}
private void verifyFindByIdIsCalledOnce() {
Mockito.verify(employeeRepository, VerificationModeFactory.times(1))
.findById(Mockito.anyLong());
Mockito.reset(employeeRepository);
}
private void verifyFindAllEmployeesIsCalledOnce() {
Mockito.verify(employeeRepository, VerificationModeFactory.times(1))
.findAll();
Mockito.reset(employeeRepository);
}
}

View File

@ -0,0 +1,14 @@
package org.baeldung.boot.boottest;
import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonUtil {
public static byte[] toJson(Object object) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.writeValueAsBytes(object);
}
}

View File

@ -0,0 +1,2 @@
spring.datasource.url = jdbc:h2:mem:test
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect

View File

@ -6,8 +6,7 @@
package com.baeldung.spring.cloud.greeting; package com.baeldung.spring.cloud.greeting;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@ -16,8 +15,7 @@ public class GreetingController {
@Autowired @Autowired
private HelloWorldClient helloWorldClient; private HelloWorldClient helloWorldClient;
@RequestMapping(value = "/get-greeting", method = RequestMethod.GET) @GetMapping("/get-greeting")
public String greeting() { public String greeting() {
return helloWorldClient.HelloWorld(); return helloWorldClient.HelloWorld();

View File

@ -5,14 +5,13 @@
*/ */
package com.baeldung.spring.cloud.helloworld; package com.baeldung.spring.cloud.helloworld;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class HelloWorldController { public class HelloWorldController {
@RequestMapping(path = "/helloworld", method = RequestMethod.GET) @GetMapping("/helloworld")
public String HelloWorld() { public String HelloWorld() {
return "Hello World!"; return "Hello World!";
} }

View File

@ -0,0 +1,17 @@
package com.baeldung.value;
public class SomeBean {
private int someValue;
public SomeBean(int someValue) {
this.someValue = someValue;
}
public int getSomeValue() {
return someValue;
}
public void setSomeValue(int someValue) {
this.someValue = someValue;
}
}

View File

@ -0,0 +1,68 @@
package com.baeldung.value;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource(name = "myProperties", value = "values.properties")
public class ValuesApp {
@Value("string value")
private String stringValue;
@Value("${value.from.file}")
private String valueFromFile;
@Value("${systemValue}")
private String systemValue;
@Value("${unknown_param:some default}")
private String someDefault;
@Value("${priority}")
private String prioritySystemProperty;
@Value("#{systemProperties['priority']}")
private String spelValue;
@Value("#{systemProperties['unknown'] ?: 'some default'}")
private String spelSomeDefault;
@Value("#{someBean.someValue}")
private Integer someBeanValue;
@Value("#{'${listOfValues}'.split(',')}")
private List<String> valuesList;
public static void main(String[] args) {
System.setProperty("systemValue", "Some system parameter value");
System.setProperty("priority", "System property");
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ValuesApp.class);
}
@Bean
public SomeBean someBean() {
return new SomeBean(10);
}
@PostConstruct
public void afterInitialize() {
System.out.println(stringValue);
System.out.println(valueFromFile);
System.out.println(systemValue);
System.out.println(someDefault);
System.out.println(prioritySystemProperty);
System.out.println(spelValue);
System.out.println(spelSomeDefault);
System.out.println(someBeanValue);
System.out.println(valuesList);
}
}

View File

@ -0,0 +1,3 @@
value.from.file=Value got from the file
priority=Properties file
listOfValues=A,B,C

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,8 +7,13 @@
</encoder> </encoder>
</appender> </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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -8,10 +8,12 @@
</appender> </appender>
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="org.baeldung" level="DEBUG" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -8,10 +8,12 @@
</appender> </appender>
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="org.baeldung" level="DEBUG" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,8 +7,13 @@
</encoder> </encoder>
</appender> </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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,20 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>elasticsearch - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern> </pattern>
</encoder> </encoder>
</appender> </appender>
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" />
<!-- in order to debug some elastic issues, this needs to be DEBUG or INFO --> <!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.elasticsearch" level="INFO" /> <logger name="org.springframework.web.servlet.mvc" level="WARN" />
<logger name="com.baeldung.spring" level="DEBUG" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,16 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%d %5p %40.40c:%4L - %m%n</pattern> <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</encoder> </encoder>
</appender> </appender>
<logger name="org.neo4j.ogm" level="info"/> <logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" />
<root level="warn"> <!-- in order to debug some marshalling issues, this needs to be TRACE -->
<appender-ref ref="console"/> <logger name="org.springframework.web.servlet.mvc" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -13,10 +13,7 @@
<!-- in order to debug some marshalling issues, this needs to be TRACE --> <!-- in order to debug some marshalling issues, this needs to be TRACE -->
<logger name="org.springframework.web.servlet.mvc" level="WARN" /> <logger name="org.springframework.web.servlet.mvc" level="WARN" />
<logger name="org.springframework.core.io.support" level="INFO" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,8 +7,6 @@
</encoder> </encoder>
</appender> </appender>
<logger name="org.hibernate" level="INFO" />
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" /> <logger name="org.springframework.transaction" level="WARN" />
@ -18,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -7,8 +7,6 @@
</encoder> </encoder>
</appender> </appender>
<logger name="org.hibernate" level="INFO" />
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" level="WARN" /> <logger name="org.springframework.transaction" level="WARN" />
@ -18,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,15 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
%message%n
</pattern> </pattern>
</encoder> </encoder>
</appender> </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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,15 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
%message%n
</pattern> </pattern>
</encoder> </encoder>
</appender> </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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern> <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
%date [%thread] %-5level %logger{6} - %message%n
</pattern> </pattern>
</encoder> </encoder>
</appender> </appender>
@ -17,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,16 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern> </pattern>
</encoder> </encoder>
</appender> </appender>
<logger name="org.springframework" level="WARN" /> <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"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -188,6 +188,12 @@
<artifactId>kryo</artifactId> <artifactId>kryo</artifactId>
<version>${kryo.version}</version> <version>${kryo.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -359,6 +365,7 @@
<!-- okhttp --> <!-- okhttp -->
<com.squareup.okhttp3.version>3.4.1</com.squareup.okhttp3.version> <com.squareup.okhttp3.version>3.4.1</com.squareup.okhttp3.version>
<json.path.version>2.2.0</json.path.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,55 @@
package org.baeldung.web.controller;
import java.util.Arrays;
import java.util.List;
import org.baeldung.web.dto.Bazz;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonProcessingException;
@RestController
@RequestMapping("/bazz")
public class BazzNewMappingsExampleController {
@GetMapping
public ResponseEntity<?> getBazzs() throws JsonProcessingException{
List<Bazz> data = Arrays.asList(
new Bazz("1", "Bazz1"),
new Bazz("2", "Bazz2"),
new Bazz("3", "Bazz3"),
new Bazz("4", "Bazz4"));
return new ResponseEntity<>(data, HttpStatus.OK);
}
@GetMapping("/{id}")
public ResponseEntity<?> getBazz(@PathVariable String id){
return new ResponseEntity<>(new Bazz(id, "Bazz"+id), HttpStatus.OK);
}
@PostMapping
public ResponseEntity<?> newBazz(@RequestParam("name") String name){
return new ResponseEntity<>(new Bazz("5", name), HttpStatus.OK);
}
@PutMapping("/{id}")
public ResponseEntity<?> updateBazz(@PathVariable String id,
@RequestParam("name") String name){
return new ResponseEntity<>(new Bazz(id, name), HttpStatus.OK);
}
@DeleteMapping("/{id}")
public ResponseEntity<?> deleteBazz(@PathVariable String id){
return new ResponseEntity<>(new Bazz(id), HttpStatus.OK);
}
}

View File

@ -0,0 +1,22 @@
package org.baeldung.web.dto;
public class Bazz {
public String id;
public String name;
public Bazz(String id){
this.id = id;
}
public Bazz(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Bazz [id=" + id + ", name=" + name + "]";
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -0,0 +1,80 @@
package org.baeldung.web.test;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.baeldung.config.WebConfig;
import org.junit.Before;
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 org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = WebConfig.class)
@WebAppConfiguration
public class BazzNewMappingsExampleControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void whenGettingAllBazz_thenSuccess() throws Exception{
mockMvc.perform(get("/bazz"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(4)))
.andExpect(jsonPath("$[1].id", is("2")))
.andExpect(jsonPath("$[1].name", is("Bazz2")));
}
@Test
public void whenGettingABazz_thenSuccess() throws Exception{
mockMvc.perform(get("/bazz/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is("1")))
.andExpect(jsonPath("$.name", is("Bazz1")));
}
@Test
public void whenAddingABazz_thenSuccess() throws Exception{
mockMvc.perform(post("/bazz").param("name", "Bazz5"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is("5")))
.andExpect(jsonPath("$.name", is("Bazz5")));
}
@Test
public void whenUpdatingABazz_thenSuccess() throws Exception{
mockMvc.perform(put("/bazz/5").param("name", "Bazz6"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is("5")))
.andExpect(jsonPath("$.name", is("Bazz6")));
}
@Test
public void whenDeletingABazz_thenSuccess() throws Exception{
mockMvc.perform(delete("/bazz/5"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is("5")));
}
}

View File

@ -24,7 +24,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception { protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService); auth.authenticationProvider(authenticationProvider());
} }
@Override @Override

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -10,13 +10,10 @@
<logger name="org.springframework" level="WARN" /> <logger name="org.springframework" level="WARN" />
<logger name="org.springframework.transaction" 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" /> <logger name="org.springframework.web.servlet.mvc" level="WARN" />
<logger name="org.springframework.boot" level="WARN" />
<logger name="org.springframework.security" level="WARN" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n <pattern>web - %date [%thread] %-5level %logger{36} - %message%n
@ -16,5 +16,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

Some files were not shown because too many files have changed in this diff Show More