Merge remote-tracking branch 'upstream/master' into craedel-spring-cloud-eureka
This commit is contained in:
commit
16e49dd8c2
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "testgitrepo"]
|
||||||
|
path = testgitrepo
|
||||||
|
url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/
|
52
cdi/pom.xml
52
cdi/pom.xml
|
@ -1,52 +1,52 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
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">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>cdi</artifactId>
|
<artifactId>cdi</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<properties>
|
|
||||||
<spring.version>4.3.1.RELEASE</spring.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.12</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-core</artifactId>
|
<artifactId>spring-core</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context</artifactId>
|
<artifactId>spring-context</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
<version>1.8.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.weld.se</groupId>
|
||||||
|
<artifactId>weld-se-core</artifactId>
|
||||||
|
<version>2.3.5.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjweaver</artifactId>
|
|
||||||
<version>1.8.9</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.jboss.weld.se/weld-se-core -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jboss.weld.se</groupId>
|
|
||||||
<artifactId>weld-se-core</artifactId>
|
|
||||||
<version>2.3.5.Final</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring.version>4.3.1.RELEASE</spring.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,12 +1,14 @@
|
||||||
package com.baeldung.interceptor;
|
package com.baeldung.interceptor;
|
||||||
|
|
||||||
import javax.interceptor.InterceptorBinding;
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.interceptor.InterceptorBinding;
|
||||||
|
|
||||||
@InterceptorBinding
|
@InterceptorBinding
|
||||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Audited {}
|
public @interface Audited {
|
||||||
|
}
|
||||||
|
|
|
@ -3,12 +3,13 @@ package com.baeldung.interceptor;
|
||||||
import javax.interceptor.AroundInvoke;
|
import javax.interceptor.AroundInvoke;
|
||||||
import javax.interceptor.Interceptor;
|
import javax.interceptor.Interceptor;
|
||||||
import javax.interceptor.InvocationContext;
|
import javax.interceptor.InvocationContext;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
@Audited @Interceptor
|
@Audited
|
||||||
|
@Interceptor
|
||||||
public class AuditedInterceptor {
|
public class AuditedInterceptor {
|
||||||
public static boolean calledBefore = false;
|
public static boolean calledBefore = false;
|
||||||
public static boolean calledAfter = false;
|
public static boolean calledAfter = false;
|
||||||
|
|
||||||
@AroundInvoke
|
@AroundInvoke
|
||||||
public Object auditMethod(InvocationContext ctx) throws Exception {
|
public Object auditMethod(InvocationContext ctx) throws Exception {
|
||||||
calledBefore = true;
|
calledBefore = true;
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
package com.baeldung.spring.aspect;
|
package com.baeldung.spring.aspect;
|
||||||
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
import java.util.List;
|
||||||
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Before;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
public class SpringTestAspect {
|
public class SpringTestAspect {
|
||||||
@Autowired
|
@Autowired
|
||||||
private List<String> accumulator;
|
private List<String> accumulator;
|
||||||
|
|
||||||
@Around("execution(* com.baeldung.spring.service.SpringSuperService.*(..))")
|
@Around("execution(* com.baeldung.spring.service.SpringSuperService.*(..))")
|
||||||
public Object advice(ProceedingJoinPoint jp) throws Throwable {
|
public Object auditMethod(ProceedingJoinPoint jp) throws Throwable {
|
||||||
String methodName = jp.getSignature().getName();
|
String methodName = jp.getSignature().getName();
|
||||||
accumulator.add("Call to " + methodName);
|
accumulator.add("Call to " + methodName);
|
||||||
Object obj = jp.proceed();
|
Object obj = jp.proceed();
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package com.baeldung.spring.configuration;
|
package com.baeldung.spring.configuration;
|
||||||
|
|
||||||
import com.baeldung.spring.aspect.SpringTestAspect;
|
import java.util.ArrayList;
|
||||||
import com.baeldung.spring.service.SpringSuperService;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.baeldung.spring.aspect.SpringTestAspect;
|
||||||
import java.util.List;
|
import com.baeldung.spring.service.SpringSuperService;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableAspectJAutoProxy
|
@EnableAspectJAutoProxy
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package com.baeldung.test;
|
package com.baeldung.test;
|
||||||
|
|
||||||
import com.baeldung.interceptor.Audited;
|
|
||||||
import com.baeldung.interceptor.AuditedInterceptor;
|
|
||||||
import com.baeldung.service.SuperService;
|
|
||||||
import org.jboss.weld.environment.se.Weld;
|
import org.jboss.weld.environment.se.Weld;
|
||||||
import org.jboss.weld.environment.se.WeldContainer;
|
import org.jboss.weld.environment.se.WeldContainer;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -10,16 +7,13 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import javax.enterprise.inject.spi.BeanManager;
|
import com.baeldung.interceptor.AuditedInterceptor;
|
||||||
import javax.enterprise.inject.spi.InterceptionType;
|
import com.baeldung.service.SuperService;
|
||||||
import javax.enterprise.inject.spi.Interceptor;
|
|
||||||
import javax.enterprise.util.AnnotationLiteral;
|
|
||||||
|
|
||||||
import static javafx.beans.binding.Bindings.select;
|
|
||||||
|
|
||||||
public class TestInterceptor {
|
public class TestInterceptor {
|
||||||
Weld weld;
|
Weld weld;
|
||||||
WeldContainer container;
|
WeldContainer container;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() {
|
public void init() {
|
||||||
weld = new Weld();
|
weld = new Weld();
|
||||||
|
@ -36,7 +30,9 @@ public class TestInterceptor {
|
||||||
SuperService superService = container.select(SuperService.class).get();
|
SuperService superService = container.select(SuperService.class).get();
|
||||||
String code = "123456";
|
String code = "123456";
|
||||||
superService.deliverService(code);
|
superService.deliverService(code);
|
||||||
|
|
||||||
Assert.assertTrue(AuditedInterceptor.calledBefore);
|
Assert.assertTrue(AuditedInterceptor.calledBefore);
|
||||||
Assert.assertTrue(AuditedInterceptor.calledAfter);
|
Assert.assertTrue(AuditedInterceptor.calledAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,18 @@
|
||||||
package com.baeldung.test;
|
package com.baeldung.test;
|
||||||
|
|
||||||
import com.baeldung.spring.configuration.AppConfig;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import com.baeldung.spring.service.SpringSuperService;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.TestExecutionListeners;
|
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
|
||||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
|
||||||
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import com.baeldung.spring.configuration.AppConfig;
|
||||||
import java.util.List;
|
import com.baeldung.spring.service.SpringSuperService;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = { AppConfig.class })
|
@ContextConfiguration(classes = { AppConfig.class })
|
||||||
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
package com.baeldung.completablefuture;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class CompletableFutureTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRunningCompletableFutureAsynchronously_thenGetMethodWaitsForResult() throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
Future<String> completableFuture = calculateAsync();
|
||||||
|
|
||||||
|
String result = completableFuture.get();
|
||||||
|
assertEquals("Hello", result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<String> calculateAsync() throws InterruptedException {
|
||||||
|
CompletableFuture<String> completableFuture = new CompletableFuture<>();
|
||||||
|
|
||||||
|
Executors.newCachedThreadPool().submit(() -> {
|
||||||
|
Thread.sleep(500);
|
||||||
|
completableFuture.complete("Hello");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return completableFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRunningCompletableFutureWithResult_thenGetMethodReturnsImmediately() throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
Future<String> completableFuture = CompletableFuture.completedFuture("Hello");
|
||||||
|
|
||||||
|
String result = completableFuture.get();
|
||||||
|
assertEquals("Hello", result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Future<String> calculateAsyncWithCancellation() throws InterruptedException {
|
||||||
|
CompletableFuture<String> completableFuture = new CompletableFuture<>();
|
||||||
|
|
||||||
|
Executors.newCachedThreadPool().submit(() -> {
|
||||||
|
Thread.sleep(500);
|
||||||
|
completableFuture.cancel(false);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return completableFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = CancellationException.class)
|
||||||
|
public void whenCancelingTheFuture_thenThrowsCancellationException() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
Future<String> future = calculateAsyncWithCancellation();
|
||||||
|
future.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreatingCompletableFutureWithSupplyAsync_thenFutureReturnsValue() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
|
||||||
|
|
||||||
|
assertEquals("Hello", future.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingThenAcceptToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
|
||||||
|
|
||||||
|
CompletableFuture<Void> future = completableFuture.thenAccept(s -> System.out.println("Computation returned: " + s));
|
||||||
|
|
||||||
|
future.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingThenRunToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
|
||||||
|
|
||||||
|
CompletableFuture<Void> future = completableFuture.thenRun(() -> System.out.println("Computation finished."));
|
||||||
|
|
||||||
|
future.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingThenApplyToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
|
||||||
|
|
||||||
|
CompletableFuture<String> future = completableFuture.thenApply(s -> s + " World");
|
||||||
|
|
||||||
|
assertEquals("Hello World", future.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingThenCompose_thenFuturesExecuteSequentially() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello")
|
||||||
|
.thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));
|
||||||
|
|
||||||
|
assertEquals("Hello World", completableFuture.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingThenCombine_thenWaitForExecutionOfBothFutures() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello")
|
||||||
|
.thenCombine(CompletableFuture.supplyAsync(() -> " World"),
|
||||||
|
(s1, s2) -> s1 + s2);
|
||||||
|
|
||||||
|
assertEquals("Hello World", completableFuture.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingThenAcceptBoth_thenWaitForExecutionOfBothFutures() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture.supplyAsync(() -> "Hello")
|
||||||
|
.thenAcceptBoth(CompletableFuture.supplyAsync(() -> " World"),
|
||||||
|
(s1, s2) -> System.out.println(s1 + s2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFutureCombinedWithAllOfCompletes_thenAllFuturesAreDone() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
|
||||||
|
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Beautiful");
|
||||||
|
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "World");
|
||||||
|
|
||||||
|
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
combinedFuture.get();
|
||||||
|
|
||||||
|
assertTrue(future1.isDone());
|
||||||
|
assertTrue(future2.isDone());
|
||||||
|
assertTrue(future3.isDone());
|
||||||
|
|
||||||
|
String combined = Stream.of(future1, future2, future3)
|
||||||
|
.map(CompletableFuture::join)
|
||||||
|
.collect(Collectors.joining(" "));
|
||||||
|
|
||||||
|
assertEquals("Hello Beautiful World", combined);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFutureThrows_thenHandleMethodReceivesException() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
String name = null;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
|
||||||
|
if (name == null) {
|
||||||
|
throw new RuntimeException("Computation error!");
|
||||||
|
}
|
||||||
|
return "Hello, " + name;
|
||||||
|
}).handle((s, t) -> s != null ? s : "Hello, Stranger!");
|
||||||
|
|
||||||
|
assertEquals("Hello, Stranger!", completableFuture.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ExecutionException.class)
|
||||||
|
public void whenCompletingFutureExceptionally_thenGetMethodThrows() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = new CompletableFuture<>();
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
completableFuture.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingThenApplyAsyncToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
|
||||||
|
|
||||||
|
CompletableFuture<String> future = completableFuture.thenApplyAsync(s -> s + " World");
|
||||||
|
|
||||||
|
assertEquals("Hello World", future.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,9 +12,9 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.4.0.RELEASE</version>
|
<version>1.4.0.RELEASE</version>
|
||||||
<relativePath></relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
||||||
<!-- General -->
|
<!-- General -->
|
||||||
|
@ -33,60 +33,68 @@
|
||||||
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
<maven-resources-plugin.version>2.7</maven-resources-plugin.version>
|
<maven-resources-plugin.version>2.7</maven-resources-plugin.version>
|
||||||
|
<hystrix-metrics-event-stream.version>1.3.16</hystrix-metrics-event-stream.version>
|
||||||
|
<hystrix-dashboard.version>1.4.3</hystrix-dashboard.version>
|
||||||
|
<spring-boot-starter-test.version>1.4.0.RELEASE</spring-boot-starter-test.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.netflix.hystrix</groupId>
|
<groupId>com.netflix.hystrix</groupId>
|
||||||
<artifactId>hystrix-core</artifactId>
|
<artifactId>hystrix-core</artifactId>
|
||||||
<version>${hystrix-core.version}</version>
|
<version>${hystrix-core.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.netflix.hystrix</groupId>
|
<groupId>com.netflix.hystrix</groupId>
|
||||||
<artifactId>hystrix-metrics-event-stream</artifactId>
|
<artifactId>hystrix-metrics-event-stream</artifactId>
|
||||||
<version>1.3.16</version>
|
<version>${hystrix-metrics-event-stream.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/com.netflix.hystrix/hystrix-dashboard -->
|
|
||||||
<!--<dependency>
|
|
||||||
<groupId>com.netflix.hystrix</groupId>
|
<groupId>com.netflix.hystrix</groupId>
|
||||||
<artifactId>hystrix-dashboard</artifactId>
|
<artifactId>hystrix-dashboard</artifactId>
|
||||||
<version>1.4.3</version>
|
<version>${hystrix-dashboard.version}</version>
|
||||||
</dependency>-->
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.netflix.rxjava</groupId>
|
<groupId>com.netflix.rxjava</groupId>
|
||||||
<artifactId>rxjava-core</artifactId>
|
<artifactId>rxjava-core</artifactId>
|
||||||
<version>${rxjava-core.version}</version>
|
<version>${rxjava-core.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-all</artifactId>
|
<artifactId>hamcrest-all</artifactId>
|
||||||
<version>${hamcrest-all.version}</version>
|
<version>${hamcrest-all.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<version>${spring-boot-starter-test.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -17,6 +17,28 @@ public class HystrixAspect {
|
||||||
private HystrixCommandProperties.Setter commandProperties;
|
private HystrixCommandProperties.Setter commandProperties;
|
||||||
private HystrixThreadPoolProperties.Setter threadPoolProperties;
|
private HystrixThreadPoolProperties.Setter threadPoolProperties;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.execution.timeout}")
|
||||||
|
private int executionTimeout;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.sleepwindow}")
|
||||||
|
private int sleepWindow;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.threadpool.maxsize}")
|
||||||
|
private int maxThreadCount;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.threadpool.coresize}")
|
||||||
|
private int coreThreadCount;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.task.queue.size}")
|
||||||
|
private int queueCount;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.group.key}")
|
||||||
|
private String groupKey;
|
||||||
|
|
||||||
|
@Value("${remoteservice.command.key}")
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
|
||||||
@Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)")
|
@Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)")
|
||||||
public Object circuitBreakerAround(final ProceedingJoinPoint aJoinPoint) {
|
public Object circuitBreakerAround(final ProceedingJoinPoint aJoinPoint) {
|
||||||
return new RemoteServiceCommand(config, aJoinPoint).execute();
|
return new RemoteServiceCommand(config, aJoinPoint).execute();
|
||||||
|
@ -58,24 +80,4 @@ public class HystrixAspect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Value("${remoteservice.command.execution.timeout}")
|
|
||||||
private int executionTimeout;
|
|
||||||
|
|
||||||
@Value("${remoteservice.command.sleepwindow}")
|
|
||||||
private int sleepWindow;
|
|
||||||
|
|
||||||
@Value("${remoteservice.command.threadpool.maxsize}")
|
|
||||||
private int maxThreadCount;
|
|
||||||
|
|
||||||
@Value("${remoteservice.command.threadpool.coresize}")
|
|
||||||
private int coreThreadCount;
|
|
||||||
|
|
||||||
@Value("${remoteservice.command.task.queue.size}")
|
|
||||||
private int queueCount;
|
|
||||||
|
|
||||||
@Value("${remoteservice.command.group.key}")
|
|
||||||
private String groupKey;
|
|
||||||
|
|
||||||
@Value("${remoteservice.command.key}")
|
|
||||||
private String key;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,13 @@ public class HystrixController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private SpringExistingClient client;
|
private SpringExistingClient client;
|
||||||
|
|
||||||
@RequestMapping("/")
|
@RequestMapping("/withHystrix")
|
||||||
public String index() throws InterruptedException{
|
public String withHystrix() throws InterruptedException{
|
||||||
return client.invokeRemoteService();
|
return client.invokeRemoteServiceWithHystrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/withOutHystrix")
|
||||||
|
public String withOutHystrix() throws InterruptedException{
|
||||||
|
return client.invokeRemoteServiceWithOutHystrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,11 @@ public class SpringExistingClient {
|
||||||
private int remoteServiceDelay;
|
private int remoteServiceDelay;
|
||||||
|
|
||||||
@HystrixCircuitBreaker
|
@HystrixCircuitBreaker
|
||||||
public String invokeRemoteService() throws InterruptedException{
|
public String invokeRemoteServiceWithHystrix() throws InterruptedException{
|
||||||
return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
|
return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String invokeRemoteServiceWithOutHystrix() throws InterruptedException{
|
||||||
|
return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,4 @@ remoteservice.command.threadpool.coresize=5
|
||||||
remoteservice.command.threadpool.maxsize=10
|
remoteservice.command.threadpool.maxsize=10
|
||||||
remoteservice.command.task.queue.size=5
|
remoteservice.command.task.queue.size=5
|
||||||
remoteservice.command.sleepwindow=5000
|
remoteservice.command.sleepwindow=5000
|
||||||
remoteservice.timeout=5000
|
remoteservice.timeout=15000
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.baeldung.hystrix;
|
||||||
|
|
||||||
|
import com.netflix.hystrix.HystrixCommand;
|
||||||
|
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||||
|
import com.netflix.hystrix.HystrixCommandProperties;
|
||||||
|
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||||
|
import com.netflix.hystrix.exception.HystrixRuntimeException;
|
||||||
|
import org.junit.*;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.JVM)
|
||||||
|
public class HystrixTimeShortCircuitTest {
|
||||||
|
|
||||||
|
private HystrixCommand.Setter config;
|
||||||
|
private HystrixCommandProperties.Setter commandProperties;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
commandProperties = HystrixCommandProperties.Setter();
|
||||||
|
config = HystrixCommand
|
||||||
|
.Setter
|
||||||
|
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCircuitBreakerSetup__whenRemoteSvcCmdExecuted_thenReturnSuccess()
|
||||||
|
throws InterruptedException {
|
||||||
|
|
||||||
|
commandProperties.withExecutionTimeoutInMilliseconds(1000);
|
||||||
|
|
||||||
|
commandProperties.withCircuitBreakerSleepWindowInMilliseconds(4000);
|
||||||
|
commandProperties.withExecutionIsolationStrategy(
|
||||||
|
HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
|
||||||
|
commandProperties.withCircuitBreakerEnabled(true);
|
||||||
|
commandProperties.withCircuitBreakerRequestVolumeThreshold(1);
|
||||||
|
|
||||||
|
config.andCommandPropertiesDefaults(commandProperties);
|
||||||
|
|
||||||
|
config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
|
||||||
|
.withMaxQueueSize(1)
|
||||||
|
.withCoreSize(1)
|
||||||
|
.withQueueSizeRejectionThreshold(1));
|
||||||
|
|
||||||
|
assertThat(this.invokeRemoteService(10000), equalTo(null));
|
||||||
|
assertThat(this.invokeRemoteService(10000), equalTo(null));
|
||||||
|
Thread.sleep(5000);
|
||||||
|
|
||||||
|
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
||||||
|
equalTo("Success"));
|
||||||
|
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
||||||
|
equalTo("Success"));
|
||||||
|
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
||||||
|
equalTo("Success"));
|
||||||
|
}
|
||||||
|
|
||||||
|
String invokeRemoteService(long timeout) throws InterruptedException {
|
||||||
|
String response = null;
|
||||||
|
try {
|
||||||
|
response = new RemoteServiceTestCommand(config,
|
||||||
|
new RemoteServiceTestSimulator(timeout)).execute();
|
||||||
|
} catch (HystrixRuntimeException ex) {
|
||||||
|
System.out.println("ex = " + ex);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,14 +5,14 @@ import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||||
import com.netflix.hystrix.HystrixCommandProperties;
|
import com.netflix.hystrix.HystrixCommandProperties;
|
||||||
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||||
import com.netflix.hystrix.exception.HystrixRuntimeException;
|
import com.netflix.hystrix.exception.HystrixRuntimeException;
|
||||||
import org.junit.Before;
|
import org.junit.*;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.JVM)
|
||||||
public class HystrixTimeoutTest {
|
public class HystrixTimeoutTest {
|
||||||
|
|
||||||
private HystrixCommand.Setter config;
|
private HystrixCommand.Setter config;
|
||||||
|
@ -31,32 +31,40 @@ public class HystrixTimeoutTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenInputBob_andDefaultSettings_thenReturnHelloBob(){
|
public void givenInputBobAndDefaultSettings_whenExecuted_thenReturnHelloBob(){
|
||||||
assertThat(new CommandHelloWorld("Bob").execute(), equalTo("Hello Bob!"));
|
assertThat(new CommandHelloWorld("Bob").execute(), equalTo("Hello Bob!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenServiceTimeoutEqualTo100_andDefaultSettings_thenReturnSuccess() throws InterruptedException {
|
public void givenSvcTimeoutOf100AndDefaultSettings_whenExecuted_thenReturnSuccess()
|
||||||
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(), equalTo("Success"));
|
throws InterruptedException {
|
||||||
|
|
||||||
|
HystrixCommand.Setter config = HystrixCommand
|
||||||
|
.Setter
|
||||||
|
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup1"));
|
||||||
|
|
||||||
|
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(),
|
||||||
|
equalTo("Success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenServiceTimeoutEqualTo10000_andDefaultSettings_thenExpectHRE() throws InterruptedException {
|
public void givenSvcTimeoutOf10000AndDefaultSettings__whenExecuted_thenExpectHRE() throws InterruptedException {
|
||||||
exception.expect(HystrixRuntimeException.class);
|
exception.expect(HystrixRuntimeException.class);
|
||||||
new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(10_000)).execute();
|
new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(10_000)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenServiceTimeoutEqualTo500_andExecutionTimeoutEqualTo10000_thenReturnSuccess()
|
public void givenSvcTimeoutOf5000AndExecTimeoutOf10000__whenExecuted_thenReturnSuccess()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
|
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
|
||||||
config.andCommandPropertiesDefaults(commandProperties);
|
config.andCommandPropertiesDefaults(commandProperties);
|
||||||
|
|
||||||
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
||||||
equalTo("Success"));
|
equalTo("Success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenServiceTimeoutEqualTo15000_andExecutionTimeoutEqualTo5000_thenExpectHRE()
|
public void givenSvcTimeoutOf15000AndExecTimeoutOf5000__whenExecuted_thenExpectHRE()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
exception.expect(HystrixRuntimeException.class);
|
exception.expect(HystrixRuntimeException.class);
|
||||||
commandProperties.withExecutionTimeoutInMilliseconds(5_000);
|
commandProperties.withExecutionTimeoutInMilliseconds(5_000);
|
||||||
|
@ -65,7 +73,7 @@ public class HystrixTimeoutTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenServiceTimeoutEqual_andExecutionTimeout_andThreadPool_thenReturnSuccess()
|
public void givenSvcTimeoutOf500AndExecTimeoutOf10000AndThreadPool__whenExecuted_thenReturnSuccess()
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
|
commandProperties.withExecutionTimeoutInMilliseconds(10_000);
|
||||||
config.andCommandPropertiesDefaults(commandProperties);
|
config.andCommandPropertiesDefaults(commandProperties);
|
||||||
|
@ -73,49 +81,8 @@ public class HystrixTimeoutTest {
|
||||||
.withMaxQueueSize(10)
|
.withMaxQueueSize(10)
|
||||||
.withCoreSize(3)
|
.withCoreSize(3)
|
||||||
.withQueueSizeRejectionThreshold(10));
|
.withQueueSizeRejectionThreshold(10));
|
||||||
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
|
||||||
equalTo("Success"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenCircuitBreakerSetup_thenReturnSuccess() throws InterruptedException {
|
|
||||||
|
|
||||||
commandProperties.withExecutionTimeoutInMilliseconds(1000);
|
|
||||||
|
|
||||||
commandProperties.withCircuitBreakerSleepWindowInMilliseconds(4000);
|
|
||||||
commandProperties.withExecutionIsolationStrategy(
|
|
||||||
HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
|
|
||||||
commandProperties.withCircuitBreakerEnabled(true);
|
|
||||||
commandProperties.withCircuitBreakerRequestVolumeThreshold(1);
|
|
||||||
|
|
||||||
config.andCommandPropertiesDefaults(commandProperties);
|
|
||||||
|
|
||||||
config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
|
|
||||||
.withMaxQueueSize(1)
|
|
||||||
.withCoreSize(1)
|
|
||||||
.withQueueSizeRejectionThreshold(1));
|
|
||||||
|
|
||||||
assertThat(this.invokeRemoteService(10000), equalTo(null));
|
|
||||||
assertThat(this.invokeRemoteService(10000), equalTo(null));
|
|
||||||
Thread.sleep(5000);
|
|
||||||
|
|
||||||
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
||||||
equalTo("Success"));
|
equalTo("Success"));
|
||||||
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
|
||||||
equalTo("Success"));
|
|
||||||
assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(),
|
|
||||||
equalTo("Success"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String invokeRemoteService(long timeout) throws InterruptedException{
|
|
||||||
String response = null;
|
|
||||||
try{
|
|
||||||
response = new RemoteServiceTestCommand(config,
|
|
||||||
new RemoteServiceTestSimulator(timeout)).execute();
|
|
||||||
}catch(HystrixRuntimeException ex){
|
|
||||||
System.out.println("ex = " + ex);
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.hystrix;
|
||||||
|
|
||||||
|
import com.netflix.hystrix.exception.HystrixRuntimeException;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = AppConfig.class)
|
||||||
|
public class SpringAndHystrixIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HystrixController hystrixController;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTimeOutOf15000_whenClientCalledWithHystrix_thenExpectHystrixRuntimeException() throws InterruptedException {
|
||||||
|
exception.expect(HystrixRuntimeException.class);
|
||||||
|
hystrixController.withHystrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTimeOutOf15000_whenClientCalledWithOutHystrix_thenExpectSuccess() throws InterruptedException {
|
||||||
|
assertThat(hystrixController.withOutHystrix(), equalTo("Success"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<name>mapstruct</name>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<org.mapstruct.version>1.0.0.Final</org.mapstruct.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-jdk8</artifactId>
|
||||||
|
<version>${org.mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>mapstruct</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.5.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>${org.mapstruct.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.baeldung.dto;
|
||||||
|
|
||||||
|
public class EmployeeDTO {
|
||||||
|
|
||||||
|
private int employeeId;
|
||||||
|
private String employeeName;
|
||||||
|
private int divisionId;
|
||||||
|
private String divisionName;
|
||||||
|
|
||||||
|
public int getEmployeeId() {
|
||||||
|
return employeeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmployeeId(int employeeId) {
|
||||||
|
this.employeeId = employeeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmployeeName() {
|
||||||
|
return employeeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmployeeName(String employeeName) {
|
||||||
|
this.employeeName = employeeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDivisionId() {
|
||||||
|
return divisionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDivisionId(int divisionId) {
|
||||||
|
this.divisionId = divisionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDivisionName() {
|
||||||
|
return divisionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDivisionName(String divisionName) {
|
||||||
|
this.divisionName = divisionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.baeldung.dto;
|
||||||
|
|
||||||
|
public class SimpleSource {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.baeldung.entity;
|
||||||
|
|
||||||
|
public class Division {
|
||||||
|
|
||||||
|
public Division() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Division(int id, String name) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.baeldung.entity;
|
||||||
|
|
||||||
|
public class Employee {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private Division division;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Division getDivision() {
|
||||||
|
return division;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDivision(Division division) {
|
||||||
|
this.division = division;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.baeldung.entity;
|
||||||
|
|
||||||
|
public class SimpleDestination {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package org.baeldung.mapper;
|
||||||
|
|
||||||
|
import org.baeldung.dto.EmployeeDTO;
|
||||||
|
import org.baeldung.entity.Employee;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface EmployeeMapper {
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(target="divisionId",source="entity.division.id"),
|
||||||
|
@Mapping(target="divisionName",source="entity.division.name"),
|
||||||
|
@Mapping(target="employeeId",source="entity.id"),
|
||||||
|
@Mapping(target="employeeName",source="entity.name")
|
||||||
|
})
|
||||||
|
EmployeeDTO employeeToEmployeeDTO(Employee entity);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(target="id",source="dto.employeeId"),
|
||||||
|
@Mapping(target="name",source="dto.employeeName"),
|
||||||
|
@Mapping(target="division",expression="java(new org.baeldung.entity.Division(dto.getDivisionId(),dto.getDivisionName()))")
|
||||||
|
})
|
||||||
|
Employee employeeDTOtoEmployee(EmployeeDTO dto);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.baeldung.mapper;
|
||||||
|
|
||||||
|
import org.baeldung.dto.SimpleSource;
|
||||||
|
import org.baeldung.entity.SimpleDestination;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SimpleSourceDestinationMapper {
|
||||||
|
|
||||||
|
SimpleDestination sourceToDestination(SimpleSource source);
|
||||||
|
SimpleSource destinationToSource(SimpleDestination destination);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.baeldung.mapper;
|
||||||
|
|
||||||
|
import org.baeldung.dto.SimpleSource;
|
||||||
|
import org.baeldung.entity.SimpleDestination;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper(componentModel="spring")
|
||||||
|
public interface SimpleSourceDestinationSpringMapper {
|
||||||
|
|
||||||
|
SimpleDestination sourceToDestination(SimpleSource source);
|
||||||
|
SimpleSource destinationToSource(SimpleDestination destination);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.baeldung.mapper;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.baeldung.dto.EmployeeDTO;
|
||||||
|
import org.baeldung.entity.Division;
|
||||||
|
import org.baeldung.entity.Employee;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
public class EmployeeMapperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmployeeDTOtoEmployee_whenMaps_thenCorrect(){
|
||||||
|
EmployeeMapper mapper = Mappers.getMapper(EmployeeMapper.class);
|
||||||
|
|
||||||
|
EmployeeDTO dto = new EmployeeDTO();
|
||||||
|
dto.setDivisionId(1);
|
||||||
|
dto.setDivisionName("IT Division");
|
||||||
|
dto.setEmployeeId(1);
|
||||||
|
dto.setEmployeeName("John");
|
||||||
|
|
||||||
|
Employee entity = mapper.employeeDTOtoEmployee(dto);
|
||||||
|
|
||||||
|
assertEquals(dto.getDivisionId(), entity.getDivision().getId());
|
||||||
|
assertEquals(dto.getDivisionName(), entity.getDivision().getName());
|
||||||
|
assertEquals(dto.getEmployeeId(),entity.getId());
|
||||||
|
assertEquals(dto.getEmployeeName(),entity.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmployeetoEmployeeDTO_whenMaps_thenCorrect(){
|
||||||
|
EmployeeMapper mapper = Mappers.getMapper(EmployeeMapper.class);
|
||||||
|
|
||||||
|
Employee entity = new Employee();
|
||||||
|
entity.setDivision(new Division(1,"IT Division"));
|
||||||
|
entity.setId(1);
|
||||||
|
entity.setName("John");
|
||||||
|
|
||||||
|
EmployeeDTO dto = mapper.employeeToEmployeeDTO(entity);
|
||||||
|
|
||||||
|
assertEquals(dto.getDivisionId(), entity.getDivision().getId());
|
||||||
|
assertEquals(dto.getDivisionName(), entity.getDivision().getName());
|
||||||
|
assertEquals(dto.getEmployeeId(),entity.getId());
|
||||||
|
assertEquals(dto.getEmployeeName(),entity.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.baeldung.mapper;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.baeldung.dto.SimpleSource;
|
||||||
|
import org.baeldung.entity.SimpleDestination;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
public class SimpleSourceDestinationMapperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleSourceToSimpleDestination_whenMaps_thenCorrect() {
|
||||||
|
SimpleSourceDestinationMapper simpleSourceDestinationMapper = Mappers
|
||||||
|
.getMapper(SimpleSourceDestinationMapper.class);
|
||||||
|
|
||||||
|
SimpleSource simpleSource = new SimpleSource();
|
||||||
|
simpleSource.setName("SourceName");
|
||||||
|
simpleSource.setDescription("SourceDescription");
|
||||||
|
|
||||||
|
SimpleDestination destination =
|
||||||
|
simpleSourceDestinationMapper.sourceToDestination(simpleSource);
|
||||||
|
|
||||||
|
assertEquals(simpleSource.getName(), destination.getName());
|
||||||
|
assertEquals(simpleSource.getDescription(), destination.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleDestinationToSourceDestination_whenMaps_thenCorrect() {
|
||||||
|
SimpleSourceDestinationMapper simpleSourceDestinationMapper = Mappers
|
||||||
|
.getMapper(SimpleSourceDestinationMapper.class);
|
||||||
|
|
||||||
|
SimpleDestination destination = new SimpleDestination();
|
||||||
|
destination.setName("DestinationName");
|
||||||
|
destination.setDescription("DestinationDescription");
|
||||||
|
|
||||||
|
SimpleSource source =
|
||||||
|
simpleSourceDestinationMapper.destinationToSource(destination);
|
||||||
|
|
||||||
|
assertEquals(destination.getName(), source.getName());
|
||||||
|
assertEquals(destination.getDescription(), source.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
pom.xml
3
pom.xml
|
@ -17,6 +17,7 @@
|
||||||
<module>apache-cxf</module>
|
<module>apache-cxf</module>
|
||||||
<module>apache-fop</module>
|
<module>apache-fop</module>
|
||||||
<module>autovalue-tutorial</module>
|
<module>autovalue-tutorial</module>
|
||||||
|
<module>cdi</module>
|
||||||
<module>core-java</module>
|
<module>core-java</module>
|
||||||
<module>core-java-8</module>
|
<module>core-java-8</module>
|
||||||
<module>couchbase-sdk-intro</module>
|
<module>couchbase-sdk-intro</module>
|
||||||
|
@ -82,7 +83,7 @@
|
||||||
<module>spring-quartz</module>
|
<module>spring-quartz</module>
|
||||||
<module>spring-spel</module>
|
<module>spring-spel</module>
|
||||||
<module>spring-rest</module>
|
<module>spring-rest</module>
|
||||||
<module>spring-rest-angular-pagination</module>
|
<module>spring-rest-angular</module>
|
||||||
<module>spring-rest-docs</module>
|
<module>spring-rest-docs</module>
|
||||||
<module>spring-cloud-config</module>
|
<module>spring-cloud-config</module>
|
||||||
<module>spring-cloud-eureka</module>
|
<module>spring-cloud-eureka</module>
|
||||||
|
|
|
@ -130,6 +130,13 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.5.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-core</artifactId>
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package org.baeldung.async;
|
package org.baeldung.async;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.scheduling.annotation.AsyncResult;
|
import org.springframework.scheduling.annotation.AsyncResult;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class AsyncComponent {
|
public class AsyncComponent {
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ public class AsyncComponent {
|
||||||
System.out.println("Execute method asynchronously " + Thread.currentThread().getName());
|
System.out.println("Execute method asynchronously " + Thread.currentThread().getName());
|
||||||
try {
|
try {
|
||||||
Thread.sleep(5000);
|
Thread.sleep(5000);
|
||||||
return new AsyncResult<String>("hello world !!!!");
|
return new AsyncResult<>("hello world !!!!");
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package org.baeldung.profiles;
|
package org.baeldung.profiles;
|
||||||
|
|
||||||
public interface DatasourceConfig {
|
public interface DatasourceConfig {
|
||||||
public void setup();
|
void setup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = "prototype")
|
||||||
|
public class AllStrategiesExampleBean implements InitializingBean {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(AllStrategiesExampleBean.class);
|
||||||
|
|
||||||
|
public AllStrategiesExampleBean() {
|
||||||
|
LOG.info("Constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
LOG.info("InitializingBean");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void postConstruct() {
|
||||||
|
LOG.info("PostConstruct");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
LOG.info("init-method");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = "prototype")
|
||||||
|
public class InitMethodExampleBean {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(InitMethodExampleBean.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
LOG.info(Arrays.asList(environment.getDefaultProfiles()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = "prototype")
|
||||||
|
public class InitializingBeanExampleBean implements InitializingBean {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(InitializingBeanExampleBean.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
LOG.info(Arrays.asList(environment.getDefaultProfiles()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope("prototype")
|
||||||
|
public class InvalidInitExampleBean {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
public InvalidInitExampleBean() {
|
||||||
|
environment.getActiveProfiles();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = "prototype")
|
||||||
|
public class LogicInConstructorExampleBean {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(LogicInConstructorExampleBean.class);
|
||||||
|
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LogicInConstructorExampleBean(Environment environment) {
|
||||||
|
this.environment = environment;
|
||||||
|
|
||||||
|
LOG.info(Arrays.asList(environment.getDefaultProfiles()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = "prototype")
|
||||||
|
public class PostConstructExampleBean {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(PostConstructExampleBean.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
LOG.info(Arrays.asList(environment.getDefaultProfiles()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan("org.baeldung.startup")
|
||||||
|
public class SpringStartupConfig {
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class StartupApplicationListenerExample implements ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(StartupApplicationListenerExample.class);
|
||||||
|
|
||||||
|
public static int counter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||||
|
LOG.info("Increment counter");
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||||
|
|
||||||
|
<bean id="initMethodExampleBean"
|
||||||
|
class="org.baeldung.startup.InitMethodExampleBean"
|
||||||
|
scope="prototype"
|
||||||
|
init-method="init">
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="allStrategiesExampleBean"
|
||||||
|
class="org.baeldung.startup.AllStrategiesExampleBean"
|
||||||
|
init-method="init">
|
||||||
|
</bean>
|
||||||
|
</beans>
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = { SpringStartupConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||||
|
public class SpringStartupTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext ctx;
|
||||||
|
|
||||||
|
@Test(expected = BeanCreationException.class)
|
||||||
|
public void whenInstantiating_shouldThrowBCE() throws Exception {
|
||||||
|
ctx.getBean(InvalidInitExampleBean.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPostConstruct_shouldLogEnv() throws Exception {
|
||||||
|
ctx.getBean(PostConstructExampleBean.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenConstructorInjection_shouldLogEnv() throws Exception {
|
||||||
|
ctx.getBean(LogicInConstructorExampleBean.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInitializingBean_shouldLogEnv() throws Exception {
|
||||||
|
ctx.getBean(InitializingBeanExampleBean.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenApplicationListener_shouldRunOnce() throws Exception {
|
||||||
|
Assertions.assertThat(StartupApplicationListenerExample.counter).isEqualTo(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.baeldung.startup;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration("classpath:startupConfig.xml")
|
||||||
|
public class SpringStartupXMLConfigTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext ctx;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPostConstruct_shouldLogEnv() throws Exception {
|
||||||
|
ctx.getBean(InitMethodExampleBean.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAllStrategies_shouldLogOrder() throws Exception {
|
||||||
|
ctx.getBean(AllStrategiesExampleBean.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -112,6 +112,23 @@
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>pl.project13.maven</groupId>
|
||||||
|
<artifactId>git-commit-id-plugin</artifactId>
|
||||||
|
<version>2.2.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>get-the-git-infos</id>
|
||||||
|
<goals>
|
||||||
|
<goal>revision</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<verbose>true</verbose>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.git;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
|
@SpringBootApplication(scanBasePackages = { "com.baeldung.git"})
|
||||||
|
public class CommitIdApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CommitIdApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
|
||||||
|
PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
|
||||||
|
c.setLocation(new ClassPathResource("git.properties"));
|
||||||
|
c.setIgnoreResourceNotFound(true);
|
||||||
|
c.setIgnoreUnresolvablePlaceholders(true);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.git;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class CommitInfoController {
|
||||||
|
|
||||||
|
@Value("${git.commit.message.short}")
|
||||||
|
private String commitMessage;
|
||||||
|
|
||||||
|
@Value("${git.branch}")
|
||||||
|
private String branch;
|
||||||
|
|
||||||
|
@Value("${git.commit.id}")
|
||||||
|
private String commitId;
|
||||||
|
|
||||||
|
@RequestMapping("/commitId")
|
||||||
|
public GitInfoDto getCommitId() {
|
||||||
|
return new GitInfoDto(commitMessage, branch, commitId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.git;
|
||||||
|
|
||||||
|
public class GitInfoDto {
|
||||||
|
private String commitMessage;
|
||||||
|
private String branch;
|
||||||
|
private String commitId;
|
||||||
|
|
||||||
|
public GitInfoDto(String commitMessage, String branch, String commitId) {
|
||||||
|
this.commitMessage = commitMessage;
|
||||||
|
this.branch = branch;
|
||||||
|
this.commitId = commitId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommitMessage() {
|
||||||
|
return commitMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBranch() {
|
||||||
|
return branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommitId() {
|
||||||
|
return commitId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,3 +27,5 @@ info.app.version=1.0.0
|
||||||
security.user.name=admin1
|
security.user.name=admin1
|
||||||
security.user.password=secret1
|
security.user.password=secret1
|
||||||
management.security.role=SUPERUSER
|
management.security.role=SUPERUSER
|
||||||
|
|
||||||
|
logging.level.org.springframework=INFO
|
|
@ -0,0 +1,14 @@
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.git;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@ContextConfiguration(classes = CommitIdApplication.class)
|
||||||
|
public class CommitIdTest {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CommitIdTest.class);
|
||||||
|
|
||||||
|
@Value("${git.commit.message.short:UNKNOWN}")
|
||||||
|
private String commitMessage;
|
||||||
|
|
||||||
|
@Value("${git.branch:UNKNOWN}")
|
||||||
|
private String branch;
|
||||||
|
|
||||||
|
@Value("${git.commit.id:UNKNOWN}")
|
||||||
|
private String commitId;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInjecting_shouldDisplay() throws Exception {
|
||||||
|
|
||||||
|
LOG.info(commitId);
|
||||||
|
LOG.info(commitMessage);
|
||||||
|
LOG.info(branch);
|
||||||
|
|
||||||
|
assertThat(commitMessage)
|
||||||
|
.isNotEqualTo("UNKNOWN");
|
||||||
|
|
||||||
|
assertThat(branch)
|
||||||
|
.isNotEqualTo("UNKNOWN");
|
||||||
|
|
||||||
|
assertThat(commitId)
|
||||||
|
.isNotEqualTo("UNKNOWN");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
FROM alpine:edge
|
||||||
|
MAINTAINER baeldung.com
|
||||||
|
RUN apk add --no-cache openjdk8
|
||||||
|
COPY files/UnlimitedJCEPolicyJDK8/* /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/
|
|
@ -0,0 +1,6 @@
|
||||||
|
FROM alpine-java:base
|
||||||
|
MAINTAINER baeldung.com
|
||||||
|
RUN apk --no-cache add netcat-openbsd
|
||||||
|
COPY files/config-client.jar /opt/spring-cloud/lib/
|
||||||
|
COPY files/config-client-entrypoint.sh /opt/spring-cloud/bin/
|
||||||
|
RUN chmod 755 /opt/spring-cloud/bin/config-client-entrypoint.sh
|
|
@ -0,0 +1,9 @@
|
||||||
|
FROM alpine-java:base
|
||||||
|
MAINTAINER baeldung.com
|
||||||
|
COPY files/config-server.jar /opt/spring-cloud/lib/
|
||||||
|
ENV SPRING_APPLICATION_JSON='{"spring": {"cloud": {"config": {"server": \
|
||||||
|
{"git": {"uri": "/var/lib/spring-cloud/config-repo", "clone-on-start": true}}}}}}'
|
||||||
|
ENTRYPOINT ["/usr/bin/java"]
|
||||||
|
CMD ["-jar", "/opt/spring-cloud/lib/config-server.jar"]
|
||||||
|
VOLUME /var/lib/spring-cloud/config-repo
|
||||||
|
EXPOSE 8888
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
while ! nc -z config-server 8888 ; do
|
||||||
|
echo "Waiting for upcoming Config Server"
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
java -jar /opt/spring-cloud/lib/config-client.jar
|
|
@ -0,0 +1,41 @@
|
||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
config-server:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.server
|
||||||
|
image: config-server:latest
|
||||||
|
expose:
|
||||||
|
- 8888
|
||||||
|
networks:
|
||||||
|
- spring-cloud-network
|
||||||
|
volumes:
|
||||||
|
- spring-cloud-config-repo:/var/lib/spring-cloud/config-repo
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
config-client:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.client
|
||||||
|
image: config-client:latest
|
||||||
|
entrypoint: /opt/spring-cloud/bin/config-client-entrypoint.sh
|
||||||
|
environment:
|
||||||
|
SPRING_APPLICATION_JSON: '{"spring": {"cloud": {"config": {"uri": "http://config-server:8888"}}}}'
|
||||||
|
expose:
|
||||||
|
- 8080
|
||||||
|
ports:
|
||||||
|
- 8080
|
||||||
|
networks:
|
||||||
|
- spring-cloud-network
|
||||||
|
links:
|
||||||
|
- config-server:config-server
|
||||||
|
depends_on:
|
||||||
|
- config-server
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
networks:
|
||||||
|
spring-cloud-network:
|
||||||
|
driver: bridge
|
||||||
|
volumes:
|
||||||
|
spring-cloud-config-repo:
|
||||||
|
external: true
|
|
@ -0,0 +1,43 @@
|
||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
config-server:
|
||||||
|
container_name: config-server
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.server
|
||||||
|
image: config-server:latest
|
||||||
|
expose:
|
||||||
|
- 8888
|
||||||
|
networks:
|
||||||
|
- spring-cloud-network
|
||||||
|
volumes:
|
||||||
|
- spring-cloud-config-repo:/var/lib/spring-cloud/config-repo
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
config-client:
|
||||||
|
container_name: config-client
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.client
|
||||||
|
image: config-client:latest
|
||||||
|
entrypoint: /opt/spring-cloud/bin/config-client-entrypoint.sh
|
||||||
|
environment:
|
||||||
|
SPRING_APPLICATION_JSON: '{"spring": {"cloud": {"config": {"uri": "http://config-server:8888"}}}}'
|
||||||
|
expose:
|
||||||
|
- 8080
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
networks:
|
||||||
|
- spring-cloud-network
|
||||||
|
links:
|
||||||
|
- config-server:config-server
|
||||||
|
depends_on:
|
||||||
|
- config-server
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
networks:
|
||||||
|
spring-cloud-network:
|
||||||
|
driver: bridge
|
||||||
|
volumes:
|
||||||
|
spring-cloud-config-repo:
|
||||||
|
external: true
|
|
@ -12,7 +12,6 @@ public class OrderDetail implements Serializable {
|
||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
public OrderDetail(){
|
public OrderDetail(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderDetail(Date orderDate, String orderDesc) {
|
public OrderDetail(Date orderDate, String orderDesc) {
|
||||||
|
@ -24,27 +23,21 @@ public class OrderDetail implements Serializable {
|
||||||
public Date getOrderDate() {
|
public Date getOrderDate() {
|
||||||
return orderDate;
|
return orderDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrderDate(Date orderDate) {
|
public void setOrderDate(Date orderDate) {
|
||||||
this.orderDate = orderDate;
|
this.orderDate = orderDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOrderDesc() {
|
public String getOrderDesc() {
|
||||||
return orderDesc;
|
return orderDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrderDesc(String orderDesc) {
|
public void setOrderDesc(String orderDesc) {
|
||||||
this.orderDesc = orderDesc;
|
this.orderDesc = orderDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getUser() {
|
public User getUser() {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUser(User user) {
|
public void setUser(User user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -52,7 +45,6 @@ public class OrderDetail implements Serializable {
|
||||||
result = prime * result + ((orderId == null) ? 0 : orderId.hashCode());
|
result = prime * result + ((orderId == null) ? 0 : orderId.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
|
@ -70,13 +62,12 @@ public class OrderDetail implements Serializable {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getOrderId() {
|
public Long getOrderId() {
|
||||||
return orderId;
|
return orderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrderId(Long orderId) {
|
public void setOrderId(Long orderId) {
|
||||||
this.orderId = orderId;
|
this.orderId = orderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ public class User implements Serializable {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.baeldung.hibernate.fetching.util;
|
package com.baeldung.hibernate.fetching.util;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
|
|
||||||
public class HibernateUtil {
|
public class HibernateUtil {
|
||||||
|
@ -10,14 +11,16 @@ public class HibernateUtil {
|
||||||
//two config files are there
|
//two config files are there
|
||||||
//one with lazy loading enabled
|
//one with lazy loading enabled
|
||||||
//another lazy = false
|
//another lazy = false
|
||||||
|
SessionFactory sf = null;
|
||||||
|
if ("lazy".equals(fetchMethod)) {
|
||||||
|
sf = new Configuration().configure("fetchingLazy.cfg.xml").buildSessionFactory();
|
||||||
|
} else {
|
||||||
|
sf = new Configuration().configure("fetching.cfg.xml").buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
final String configFileName = "lazy".equals(fetchMethod) ?
|
// fetching.cfg.xml is used for this example
|
||||||
"fetchingLazy.cfg.xml" :
|
final Session session = sf.openSession();
|
||||||
"fetching.cfg.xml";
|
return session;
|
||||||
|
|
||||||
return new Configuration()
|
|
||||||
.configure(configFileName)
|
|
||||||
.buildSessionFactory().openSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Session getHibernateSession() {
|
public static Session getHibernateSession() {
|
||||||
|
|
|
@ -22,25 +22,27 @@ public class FetchingAppView {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean lazyLoaded() {
|
//lazily loaded
|
||||||
|
public Set<OrderDetail> lazyLoaded(){
|
||||||
final Session sessionLazy = HibernateUtil.getHibernateSession("lazy");
|
final Session sessionLazy = HibernateUtil.getHibernateSession("lazy");
|
||||||
List<User> users = sessionLazy.createQuery("From User").list();
|
List<User> users = sessionLazy.createQuery("From User").list();
|
||||||
User userLazyLoaded = users.get(3);
|
User userLazyLoaded = new User();
|
||||||
|
userLazyLoaded = users.get(3);
|
||||||
//since data is lazyloaded so data won't be initialized
|
//since data is lazyloaded so data won't be initialized
|
||||||
Set<OrderDetail> orderDetailSet = userLazyLoaded.getOrderDetail();
|
Set<OrderDetail> orderDetailSet = userLazyLoaded.getOrderDetail();
|
||||||
|
return (orderDetailSet);
|
||||||
return (Hibernate.isInitialized(orderDetailSet));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean eagerLoaded() {
|
//eagerly loaded
|
||||||
|
public Set<OrderDetail> eagerLoaded(){
|
||||||
final Session sessionEager = HibernateUtil.getHibernateSession();
|
final Session sessionEager = HibernateUtil.getHibernateSession();
|
||||||
//data should be loaded in the following line
|
//data should be loaded in the following line
|
||||||
//also note the queries generated
|
//also note the queries generated
|
||||||
List<User> users =sessionEager.createQuery("From User").list();
|
List<User> users =sessionEager.createQuery("From User").list();
|
||||||
User userEagerLoaded = users.get(3);
|
User userEagerLoaded = new User();
|
||||||
|
userEagerLoaded = users.get(3);
|
||||||
Set<OrderDetail> orderDetailSet = userEagerLoaded.getOrderDetail();
|
Set<OrderDetail> orderDetailSet = userEagerLoaded.getOrderDetail();
|
||||||
|
return orderDetailSet;
|
||||||
return (Hibernate.isInitialized(orderDetailSet));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +51,8 @@ public class FetchingAppView {
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
|
|
||||||
final Session session = HibernateUtil.getHibernateSession();
|
final Session session = HibernateUtil.getHibernateSession();
|
||||||
Transaction tx = session.beginTransaction();
|
Transaction tx = null;
|
||||||
|
tx = session.beginTransaction();
|
||||||
final User user1 = new User();
|
final User user1 = new User();
|
||||||
final User user2 = new User();
|
final User user2 = new User();
|
||||||
final User user3 = new User();
|
final User user3 = new User();
|
||||||
|
@ -96,15 +98,14 @@ public class FetchingAppView {
|
||||||
order5.setOrderDate(new Date(2014, 9, 11));
|
order5.setOrderDate(new Date(2014, 9, 11));
|
||||||
order5.setUser(user3);
|
order5.setUser(user3);
|
||||||
|
|
||||||
|
|
||||||
session.saveOrUpdate(order1);
|
session.saveOrUpdate(order1);
|
||||||
session.saveOrUpdate(order2);
|
session.saveOrUpdate(order2);
|
||||||
session.saveOrUpdate(order3);
|
session.saveOrUpdate(order3);
|
||||||
session.saveOrUpdate(order4);
|
session.saveOrUpdate(order4);
|
||||||
session.saveOrUpdate(order5);
|
session.saveOrUpdate(order5);
|
||||||
|
|
||||||
// session.saveOrUpdate(user1);
|
|
||||||
tx.commit();
|
tx.commit();
|
||||||
session.close();
|
session.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,43 @@
|
||||||
package com.baeldung.hibernate.fetching;
|
package com.baeldung.hibernate.fetching;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.fetching.model.OrderDetail;
|
||||||
|
|
||||||
import com.baeldung.hibernate.fetching.view.FetchingAppView;
|
import com.baeldung.hibernate.fetching.view.FetchingAppView;
|
||||||
|
|
||||||
public class HibernateFetchingTest {
|
public class HibernateFetchingTest {
|
||||||
|
|
||||||
|
|
||||||
|
//this loads sample data in the database
|
||||||
|
@Before
|
||||||
|
public void addFecthingTestData(){
|
||||||
|
FetchingAppView fav = new FetchingAppView();
|
||||||
|
fav.createTestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
//testLazyFetching() tests the lazy loading
|
||||||
|
//Since it lazily loaded so orderDetalSetLazy won't
|
||||||
|
//be initialized
|
||||||
@Test
|
@Test
|
||||||
public void testLazyFetching() {
|
public void testLazyFetching() {
|
||||||
FetchingAppView fav = new FetchingAppView();
|
FetchingAppView fav = new FetchingAppView();
|
||||||
fav.createTestData();
|
Set<OrderDetail> orderDetalSetLazy = fav.lazyLoaded();
|
||||||
assertFalse(fav.lazyLoaded());
|
assertFalse(Hibernate.isInitialized(orderDetalSetLazy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//testEagerFetching() tests the eager loading
|
||||||
|
//Since it eagerly loaded so orderDetalSetLazy would
|
||||||
|
//be initialized
|
||||||
@Test
|
@Test
|
||||||
public void testEagerFetching() {
|
public void testEagerFetching() {
|
||||||
FetchingAppView fav = new FetchingAppView();
|
FetchingAppView fav = new FetchingAppView();
|
||||||
assertTrue(fav.eagerLoaded());
|
Set<OrderDetail> orderDetalSetEager = fav.eagerLoaded();
|
||||||
|
assertTrue(Hibernate.isInitialized(orderDetalSetEager));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package org.baeldung.mock;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.baeldung.web.vo.Student;
|
|
||||||
|
|
||||||
public class MockStudentData {
|
|
||||||
|
|
||||||
private static List<Student> studentList = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
studentList.add(new Student("1", "Bryan", "Male", 20));
|
|
||||||
studentList.add(new Student("2", "Ben", "Male", 22));
|
|
||||||
studentList.add(new Student("3", "Lisa", "Female", 24));
|
|
||||||
studentList.add(new Student("4", "Sarah", "Female", 26));
|
|
||||||
studentList.add(new Student("5", "Jay", "Male", 20));
|
|
||||||
studentList.add(new Student("6", "John", "Male", 22));
|
|
||||||
studentList.add(new Student("7", "Jordan", "Male", 24));
|
|
||||||
studentList.add(new Student("8", "Rob", "Male", 26));
|
|
||||||
studentList.add(new Student("9", "Will", "Male", 20));
|
|
||||||
studentList.add(new Student("10", "Shawn", "Male", 22));
|
|
||||||
studentList.add(new Student("11", "Taylor", "Female", 24));
|
|
||||||
studentList.add(new Student("12", "Venus", "Female", 26));
|
|
||||||
studentList.add(new Student("13", "Vince", "Male", 20));
|
|
||||||
studentList.add(new Student("14", "Carol", "Female", 22));
|
|
||||||
studentList.add(new Student("15", "Joana", "Female", 24));
|
|
||||||
studentList.add(new Student("16", "Dion", "Male", 26));
|
|
||||||
studentList.add(new Student("17", "Evans", "Male", 20));
|
|
||||||
studentList.add(new Student("18", "Bart", "Male", 22));
|
|
||||||
studentList.add(new Student("19", "Jenny", "Female", 24));
|
|
||||||
studentList.add(new Student("20", "Kristine", "Female", 26));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Student> getMockDataStudents(){
|
|
||||||
return studentList;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package org.baeldung.web.rest;
|
|
||||||
|
|
||||||
import org.baeldung.web.service.StudentService;
|
|
||||||
import org.baeldung.web.vo.Student;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class StudentDirectoryRestController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private StudentService service;
|
|
||||||
|
|
||||||
@RequestMapping(value = "/student/get", params = { "page", "size" }, method = RequestMethod.GET, produces = "application/json")
|
|
||||||
public Page<Student> findPaginated(@RequestParam("page") int page, @RequestParam("size") int size){
|
|
||||||
|
|
||||||
Page<Student> resultPage = service.findPaginated(page, size);
|
|
||||||
|
|
||||||
return resultPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package org.baeldung.web.service;
|
|
||||||
|
|
||||||
import org.baeldung.web.vo.Student;
|
|
||||||
|
|
||||||
public interface StudentService extends IOperations<Student>{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package org.baeldung.web.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.baeldung.mock.MockStudentData;
|
|
||||||
import org.baeldung.web.exception.MyResourceNotFoundException;
|
|
||||||
import org.baeldung.web.vo.Student;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageImpl;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class StudentServiceImpl implements StudentService {
|
|
||||||
|
|
||||||
private List<Student> mockDataStudent = MockStudentData.getMockDataStudents();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Page<Student> findPaginated(int page, int size){
|
|
||||||
Page<Student> studentPage = getPage(page, size);
|
|
||||||
return studentPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Page<Student> getPage(int page, int size) {
|
|
||||||
page = page != 0?page - 1:page;
|
|
||||||
int from = Math.max(0, page * size);
|
|
||||||
int to = Math.min(mockDataStudent.size(), (page + 1) * size);
|
|
||||||
if(from > to){
|
|
||||||
throw new MyResourceNotFoundException("page number is higher than total pages.");
|
|
||||||
}
|
|
||||||
return new PageImpl<Student>(mockDataStudent.subList(from, to),
|
|
||||||
new PageRequest(page,size),
|
|
||||||
mockDataStudent.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package org.baeldung.web.vo;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class Student implements Serializable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public Student() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Student(String studentId, String name, String gender, Integer age) {
|
|
||||||
super();
|
|
||||||
this.studentId = studentId;
|
|
||||||
this.name = name;
|
|
||||||
this.gender = gender;
|
|
||||||
this.age = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String studentId;
|
|
||||||
private String name;
|
|
||||||
private String gender;
|
|
||||||
private Integer age;
|
|
||||||
|
|
||||||
public String getStudentId() {
|
|
||||||
return studentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStudentId(String studentId) {
|
|
||||||
this.studentId = studentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGender() {
|
|
||||||
return gender;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGender(String gender) {
|
|
||||||
this.gender = gender;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getAge() {
|
|
||||||
return age;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAge(Integer age) {
|
|
||||||
this.age = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
server.contextPath=/
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" ng-app="app">
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.css">
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
|
|
||||||
<script src="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.js"></script>
|
|
||||||
<script src="view/app.js"></script>
|
|
||||||
</head>
|
|
||||||
<body >
|
|
||||||
<div ng-controller="StudentCtrl as vm">
|
|
||||||
<div ui-grid="gridOptions" class="grid" ui-grid-pagination></div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -3,8 +3,8 @@
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>angular-spring-rest-sample</artifactId>
|
<artifactId>spring-rest-angular</artifactId>
|
||||||
<name>angular-spring-rest-sample</name>
|
<name>spring-rest-angular</name>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
@ -13,9 +13,6 @@
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.3.3.RELEASE</version>
|
<version>1.3.3.RELEASE</version>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
|
||||||
<spring.data.version>1.12.2.RELEASE</spring.data.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -30,6 +27,15 @@
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-commons</artifactId>
|
<artifactId>spring-data-commons</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.baeldung.web.dao;
|
||||||
|
|
||||||
|
import org.baeldung.web.entity.Student;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface StudentRepository extends JpaRepository<Student, Long> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package org.baeldung.web.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Student implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public Student() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Student(long id, String name, String gender, Integer age) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.gender = gender;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private long id;
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String gender;
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Integer age;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGender() {
|
||||||
|
return gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGender(String gender) {
|
||||||
|
this.gender = gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(Integer age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,5 +23,4 @@ public class MyResourceNotFoundException extends RuntimeException {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,16 +4,15 @@ import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableAutoConfiguration
|
@EnableAutoConfiguration
|
||||||
@ComponentScan("org.baeldung")
|
@Import(PersistenceConfig.class)
|
||||||
public class Application extends WebMvcConfigurerAdapter {
|
public class Application extends WebMvcConfigurerAdapter {
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(Application.class, args);
|
SpringApplication.run(Application.class, args);
|
||||||
}
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.baeldung.web.main;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.boot.orm.jpa.EntityScan;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||||
|
|
||||||
|
@EnableJpaRepositories("org.baeldung.web.dao")
|
||||||
|
@ComponentScan(basePackages = { "org.baeldung.web" })
|
||||||
|
@EntityScan("org.baeldung.web.entity")
|
||||||
|
@Configuration
|
||||||
|
public class PersistenceConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JdbcTemplate getJdbcTemplate() {
|
||||||
|
return new JdbcTemplate(dataSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||||
|
EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL).addScript("db/sql/data.sql").build();
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package org.baeldung.web.rest;
|
||||||
|
|
||||||
|
import org.baeldung.web.entity.Student;
|
||||||
|
import org.baeldung.web.exception.MyResourceNotFoundException;
|
||||||
|
import org.baeldung.web.service.StudentService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class StudentDirectoryRestController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StudentService service;
|
||||||
|
|
||||||
|
@RequestMapping(value = "/student/get", params = { "page", "size" }, method = RequestMethod.GET, produces = "application/json")
|
||||||
|
public Page<Student> findPaginated(@RequestParam("page") int page, @RequestParam("size") int size) {
|
||||||
|
|
||||||
|
Page<Student> resultPage = service.findPaginated(page, size);
|
||||||
|
if (page > resultPage.getTotalPages()) {
|
||||||
|
throw new MyResourceNotFoundException();
|
||||||
|
}
|
||||||
|
return resultPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,6 @@ import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
public interface IOperations<T> {
|
public interface IOperations<T> {
|
||||||
|
|
||||||
Page<T> findPaginated(int page, int size);
|
public Page<T> findPaginated(final int page, final int size);
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.baeldung.web.service;
|
||||||
|
|
||||||
|
import org.baeldung.web.entity.Student;
|
||||||
|
|
||||||
|
public interface StudentService extends IOperations<Student> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.baeldung.web.service;
|
||||||
|
|
||||||
|
import org.baeldung.web.dao.StudentRepository;
|
||||||
|
import org.baeldung.web.entity.Student;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class StudentServiceImpl implements StudentService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StudentRepository dao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<Student> findPaginated(int page, int size) {
|
||||||
|
return dao.findAll(new PageRequest(page, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
server.contextPath=/
|
||||||
|
spring.h2.console.enabled=true
|
||||||
|
logging.level.org.hibernate.SQL=info
|
||||||
|
spring.jpa.hibernate.ddl-auto=none
|
|
@ -0,0 +1,47 @@
|
||||||
|
CREATE TABLE student (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name VARCHAR(30),
|
||||||
|
gender VARCHAR(10),
|
||||||
|
age INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (1,'Bryan', 'Male',20);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (2, 'Ben', 'Male', 22);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (3,'Lisa', 'Female',24);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (4,'Sarah', 'Female',20);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (5,'Jay', 'Male',20);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (6,'John', 'Male',22);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (7,'Jordan', 'Male',24);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (8,'Rob', 'Male',26);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (9,'Will', 'Male',20);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (10,'Shawn', 'Male',22);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (11,'Taylor', 'Female',24);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (12,'Venus', 'Female',26);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (13,'Vince', 'Male',20);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (14,'Carol', 'Female',22);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (15,'Joana', 'Female',24);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (16,'Dion', 'Male',26);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (17,'Evans', 'Male',20);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (18,'Bart', 'Male',22);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (19,'Jenny', 'Female',24);
|
||||||
|
INSERT INTO student (id,name,gender,age)
|
||||||
|
VALUES (20,'Kristine', 'Female',26);
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" ng-app="app">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="//cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.css">
|
||||||
|
<script
|
||||||
|
src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
|
||||||
|
<script
|
||||||
|
src="//cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.js"></script>
|
||||||
|
<script src="view/app.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div ng-controller="StudentCtrl as vm">
|
||||||
|
<div ui-grid="gridOptions" class="grid" ui-grid-pagination></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -19,7 +19,7 @@ app.controller('StudentCtrl', ['$scope','StudentService', function ($scope,Stude
|
||||||
enableColumnMenus:false,
|
enableColumnMenus:false,
|
||||||
useExternalPagination: true,
|
useExternalPagination: true,
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ name: 'studentId' },
|
{ name: 'id' },
|
||||||
{ name: 'name' },
|
{ name: 'name' },
|
||||||
{ name: 'gender' },
|
{ name: 'gender' },
|
||||||
{ name: 'age' }
|
{ name: 'age' }
|
||||||
|
@ -42,6 +42,7 @@ app.controller('StudentCtrl', ['$scope','StudentService', function ($scope,Stude
|
||||||
app.service('StudentService',['$http', function ($http) {
|
app.service('StudentService',['$http', function ($http) {
|
||||||
|
|
||||||
function getStudents(pageNumber,size) {
|
function getStudents(pageNumber,size) {
|
||||||
|
pageNumber = pageNumber > 0?pageNumber - 1:0;
|
||||||
return $http({
|
return $http({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: 'student/get?page='+pageNumber+'&size='+size
|
url: 'student/get?page='+pageNumber+'&size='+size
|
|
@ -9,9 +9,10 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
|
||||||
import static io.restassured.RestAssured.given;
|
import static io.restassured.RestAssured.*;
|
||||||
import static org.hamcrest.core.IsCollectionContaining.hasItems;
|
import static org.hamcrest.core.IsCollectionContaining.*;
|
||||||
import static org.hamcrest.core.IsEqual.equalTo;
|
import static org.hamcrest.core.Is.*;
|
||||||
|
import static org.hamcrest.core.IsEqual.*;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringApplicationConfiguration(classes = Application.class)
|
@SpringApplicationConfiguration(classes = Application.class)
|
||||||
|
@ -23,58 +24,42 @@ public class StudentServiceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenPageIsOne_expectContainsNames() {
|
public void givenRequestForStudents_whenPageIsOne_expectContainsNames() {
|
||||||
given().params("page", "1", "size", "2").get(ENDPOINT)
|
given().params("page", "0", "size", "2").get(ENDPOINT).then().assertThat().body("content.name", hasItems("Bryan", "Ben"));
|
||||||
.then()
|
|
||||||
.assertThat().body("content.name", hasItems("Bryan", "Ben"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenSizeIsTwo_expectTwoItems() {
|
public void givenRequestForStudents_whenSizeIsTwo_expectTwoItems() {
|
||||||
given().params("page", "1", "size", "2").get(ENDPOINT)
|
given().params("page", "0", "size", "2").get(ENDPOINT).then().assertThat().body("size", equalTo(2));
|
||||||
.then()
|
|
||||||
.assertThat().body("size", equalTo(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenSizeIsTwo_expectNumberOfElementsTwo() {
|
public void givenRequestForStudents_whenSizeIsTwo_expectNumberOfElementsTwo() {
|
||||||
given().params("page", "1", "size", "2").get(ENDPOINT)
|
given().params("page", "0", "size", "2").get(ENDPOINT).then().assertThat().body("numberOfElements", equalTo(2));
|
||||||
.then()
|
|
||||||
.assertThat().body("numberOfElements", equalTo(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenResourcesAreRetrievedPaged_thenExpect200() {
|
public void givenRequestForStudents_whenResourcesAreRetrievedPaged_thenExpect200() {
|
||||||
given().params("page", "1", "size", "2").get(ENDPOINT)
|
given().params("page", "0", "size", "2").get(ENDPOINT).then().statusCode(200);
|
||||||
.then()
|
|
||||||
.statusCode(200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenPageOfResourcesAreRetrievedOutOfBounds_thenExpect500() {
|
public void givenRequestForStudents_whenPageOfResourcesAreRetrievedOutOfBounds_thenExpect500() {
|
||||||
given().params("page", "1000", "size", "2").get(ENDPOINT)
|
given().params("page", "1000", "size", "2").get(ENDPOINT).then().statusCode(500);
|
||||||
.then()
|
|
||||||
.statusCode(500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenPageNotValid_thenExpect500() {
|
public void givenRequestForStudents_whenPageNotValid_thenExpect500() {
|
||||||
given().params("page", RandomStringUtils.randomNumeric(5), "size", "2").get(ENDPOINT)
|
given().params("page", RandomStringUtils.randomNumeric(5), "size", "2").get(ENDPOINT).then().statusCode(500);
|
||||||
.then()
|
|
||||||
.statusCode(500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenRequestForStudents_whenPageIsFive_expectFiveItems() {
|
public void givenRequestForStudents_whenPageSizeIsFive_expectFiveItems() {
|
||||||
given().params("page", "1", "size", "5").get(ENDPOINT)
|
given().params("page", "0", "size", "5").get(ENDPOINT).then().body("content.size()", is(5));
|
||||||
.then()
|
|
||||||
.body("content.studentId.max()", equalTo("5"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources() {
|
public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources() {
|
||||||
given().params("page", "1", "size", "2").get(ENDPOINT)
|
given().params("page", "0", "size", "2").get(ENDPOINT).then().assertThat().body("first", equalTo(true));
|
||||||
.then()
|
|
||||||
.assertThat().body("first", equalTo(true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.baeldung.web.interceptor;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import org.baeldung.spring.PersistenceConfig;
|
||||||
|
import org.baeldung.spring.SecurityWithoutCsrfConfig;
|
||||||
|
import org.baeldung.spring.WebConfig;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
|
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.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
@Transactional
|
||||||
|
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class })
|
||||||
|
public class LoggerInterceptorTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WebApplicationContext wac;
|
||||||
|
@Autowired
|
||||||
|
MockHttpSession session;
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After execution of HTTP GET logs from interceptor will be displayed in
|
||||||
|
* the console
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testInterceptors() throws Exception {
|
||||||
|
mockMvc.perform(get("/graph.html")).andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue