Merge remote-tracking branch 'upstream/master' into craedel-spring-cloud-config

This commit is contained in:
Christian Raedel 2016-08-26 04:33:45 +02:00
commit 2396a959f7
309 changed files with 10370 additions and 806 deletions

3
.gitmodules vendored Normal file
View File

@ -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 Normal file
View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>cdi</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<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>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<spring.version>4.3.1.RELEASE</spring.version>
</properties>
</project>

View File

@ -0,0 +1,14 @@
package com.baeldung.interceptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
@InterceptorBinding
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Audited {
}

View File

@ -0,0 +1,20 @@
package com.baeldung.interceptor;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Audited
@Interceptor
public class AuditedInterceptor {
public static boolean calledBefore = false;
public static boolean calledAfter = false;
@AroundInvoke
public Object auditMethod(InvocationContext ctx) throws Exception {
calledBefore = true;
Object result = ctx.proceed();
calledAfter = true;
return result;
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.service;
import com.baeldung.interceptor.Audited;
public class SuperService {
@Audited
public String deliverService(String uid) {
return uid;
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.spring.aspect;
import java.util.List;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
@Aspect
public class SpringTestAspect {
@Autowired
private List<String> accumulator;
@Around("execution(* com.baeldung.spring.service.SpringSuperService.*(..))")
public Object auditMethod(ProceedingJoinPoint jp) throws Throwable {
String methodName = jp.getSignature().getName();
accumulator.add("Call to " + methodName);
Object obj = jp.proceed();
accumulator.add("Method called successfully: " + methodName);
return obj;
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.spring.configuration;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.baeldung.spring.aspect.SpringTestAspect;
import com.baeldung.spring.service.SpringSuperService;
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
@Bean
public SpringSuperService springSuperService() {
return new SpringSuperService();
}
@Bean
public SpringTestAspect springTestAspect() {
return new SpringTestAspect();
}
@Bean
public List<String> getAccumulator() {
return new ArrayList<String>();
}
}

View File

@ -0,0 +1,7 @@
package com.baeldung.spring.service;
public class SpringSuperService {
public String getInfoFromService(String code) {
return code;
}
}

View File

@ -0,0 +1,8 @@
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_2.xsd">
<interceptors>
<class>com.baeldung.interceptor.AuditedInterceptor</class>
</interceptors>
</beans>

View File

@ -0,0 +1,38 @@
package com.baeldung.test;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.interceptor.AuditedInterceptor;
import com.baeldung.service.SuperService;
public class TestInterceptor {
Weld weld;
WeldContainer container;
@Before
public void init() {
weld = new Weld();
container = weld.initialize();
}
@After
public void shutdown() {
weld.shutdown();
}
@Test
public void givenTheService_whenMethodAndInterceptorExecuted_thenOK() {
SuperService superService = container.select(SuperService.class).get();
String code = "123456";
superService.deliverService(code);
Assert.assertTrue(AuditedInterceptor.calledBefore);
Assert.assertTrue(AuditedInterceptor.calledAfter);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.test;
import static org.hamcrest.CoreMatchers.is;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.spring.configuration.AppConfig;
import com.baeldung.spring.service.SpringSuperService;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { AppConfig.class })
public class TestSpringInterceptor {
@Autowired
SpringSuperService springSuperService;
@Autowired
private List<String> accumulator;
@Test
public void givenService_whenServiceAndAspectExecuted_thenOk() {
String code = "123456";
String result = springSuperService.getInfoFromService(code);
Assert.assertThat(accumulator.size(), is(2));
Assert.assertThat(accumulator.get(0), is("Call to getInfoFromService"));
Assert.assertThat(accumulator.get(1), is("Method called successfully: getInfoFromService"));
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.threadpool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;
public class CountingTask extends RecursiveTask<Integer> {
private final TreeNode node;
public CountingTask(TreeNode node) {
this.node = node;
}
@Override
protected Integer compute() {
return node.value + node.children.stream()
.map(childNode -> new CountingTask(childNode).fork())
.collect(Collectors.summingInt(ForkJoinTask::join));
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.google.common.util.concurrent.MoreExecutors;
/**
* This class demonstrates the usage of Guava's exiting executor services that keep the VM from hanging.
* Without the exiting executor service, the task would hang indefinitely.
* This behaviour cannot be demonstrated in JUnit tests, as JUnit kills the VM after the tests.
*/
public class ExitingExecutorServiceExample {
public static void main(String... args) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
ExecutorService executorService = MoreExecutors.getExitingExecutorService(executor, 100, TimeUnit.MILLISECONDS);
executorService.submit(() -> {
while (true) {
}
});
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.threadpool;
import java.util.Set;
import com.google.common.collect.Sets;
public class TreeNode {
int value;
Set<TreeNode> children;
public TreeNode(int value, TreeNode... children) {
this.value = value;
this.children = Sets.newHashSet(children);
}
}

View File

@ -0,0 +1,53 @@
package com.baeldung;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class CharToStringTest {
@Test
public void givenChar_whenCallingStringValueOf_shouldConvertToString(){
final char givenChar = 'x';
final String result = String.valueOf(givenChar);
assertThat(result).isEqualTo("x");
}
@Test
public void givenChar_whenCallingToStringOnCharacter_shouldConvertToString(){
final char givenChar = 'x';
final String result = Character.toString(givenChar);
assertThat(result).isEqualTo("x");
}
@Test
public void givenChar_whenCallingCharacterConstructor_shouldConvertToString3(){
final char givenChar = 'x';
final String result = new Character(givenChar).toString();
assertThat(result).isEqualTo("x");
}
@Test
public void givenChar_whenConcatenated_shouldConvertToString4(){
final char givenChar = 'x';
final String result = givenChar + "";
assertThat(result).isEqualTo("x");
}
@Test
public void givenChar_whenFormated_shouldConvertToString5(){
final char givenChar = 'x';
final String result = String.format("%c", givenChar);
assertThat(result).isEqualTo("x");
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class RandomListElementTest {
@Test
public void givenList_whenRandomNumberChosen_shouldReturnARandomElement() {
List<Integer> givenList = Arrays.asList(1, 2, 3);
Random rand = new Random();
givenList.get(rand.nextInt(givenList.size()));
}
}

View File

@ -0,0 +1,62 @@
package com.baeldung;
import com.google.common.primitives.Ints;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class StringToIntOrIntegerTest {
@Test
public void givenString_whenParsingInt_shouldConvertToInt() {
String givenString = "42";
int result = Integer.parseInt(givenString);
assertThat(result).isEqualTo(42);
}
@Test
public void givenString_whenCallingIntegerValueOf_shouldConvertToInt() {
String givenString = "42";
Integer result = Integer.valueOf(givenString);
assertThat(result).isEqualTo(new Integer(42));
}
@Test
public void givenString_whenCallingIntegerConstructor_shouldConvertToInt() {
String givenString = "42";
Integer result = new Integer(givenString);
assertThat(result).isEqualTo(new Integer(42));
}
@Test
public void givenString_whenCallingIntegerDecode_shouldConvertToInt() {
String givenString = "42";
int result = Integer.decode(givenString);
assertThat(result).isEqualTo(42);
}
@Test
public void givenString_whenTryParse_shouldConvertToInt() {
String givenString = "42";
Integer result = Ints.tryParse(givenString);
assertThat(result).isEqualTo(42);
}
@Test(expected = NumberFormatException.class)
public void givenInvalidInput_whenParsingInt_shouldThrow() {
String givenString = "nan";
Integer.parseInt(givenString);
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,199 @@
package com.baeldung.functionalinterface;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.Test;
import static org.junit.Assert.*;
public class FunctionalInterfaceTest {
@Test
public void whenPassingLambdaToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() {
Map<String, Integer> nameMap = new HashMap<>();
Integer value = nameMap.computeIfAbsent("John", s -> s.length());
assertEquals(new Integer(4), nameMap.get("John"));
assertEquals(new Integer(4), value);
}
@Test
public void whenPassingMethodReferenceToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() {
Map<String, Integer> nameMap = new HashMap<>();
Integer value = nameMap.computeIfAbsent("John", String::length);
assertEquals(new Integer(4), nameMap.get("John"));
assertEquals(new Integer(4), value);
}
public byte[] transformArray(short[] array, ShortToByteFunction function) {
byte[] transformedArray = new byte[array.length];
for (int i = 0; i < array.length; i++) {
transformedArray[i] = function.applyAsByte(array[i]);
}
return transformedArray;
}
@Test
public void whenUsingCustomFunctionalInterfaceForPrimitives_thenCanUseItAsLambda() {
short[] array = {(short) 1, (short) 2, (short) 3};
byte[] transformedArray = transformArray(array, s -> (byte) (s * 2));
byte[] expectedArray = {(byte) 2, (byte) 4, (byte) 6};
assertArrayEquals(expectedArray, transformedArray);
}
@Test
public void whenUsingBiFunction_thenCanUseItToReplaceMapValues() {
Map<String, Integer> salaries = new HashMap<>();
salaries.put("John", 40000);
salaries.put("Freddy", 30000);
salaries.put("Samuel", 50000);
salaries.replaceAll((name, oldValue) -> name.equals("Freddy") ? oldValue : oldValue + 10000);
assertEquals(new Integer(50000), salaries.get("John"));
assertEquals(new Integer(30000), salaries.get("Freddy"));
assertEquals(new Integer(60000), salaries.get("Samuel"));
}
@Test
public void whenPassingLambdaToThreadConstructor_thenLambdaInferredToRunnable() {
Thread thread = new Thread(() -> System.out.println("Hello From Another Thread"));
thread.start();
}
@Test
public void whenUsingSupplierToGenerateNumbers_thenCanUseItInStreamGenerate() {
int[] fibs = {0, 1};
Stream<Integer> fibonacci = Stream.generate(() -> {
int result = fibs[1];
int fib3 = fibs[0] + fibs[1];
fibs[0] = fibs[1];
fibs[1] = fib3;
return result;
});
List<Integer> fibonacci5 = fibonacci.limit(5)
.collect(Collectors.toList());
assertEquals(new Integer(1), fibonacci5.get(0));
assertEquals(new Integer(1), fibonacci5.get(1));
assertEquals(new Integer(2), fibonacci5.get(2));
assertEquals(new Integer(3), fibonacci5.get(3));
assertEquals(new Integer(5), fibonacci5.get(4));
}
@Test
public void whenUsingConsumerInForEach_thenConsumerExecutesForEachListElement() {
List<String> names = Arrays.asList("John", "Freddy", "Samuel");
names.forEach(name -> System.out.println("Hello, " + name));
}
@Test
public void whenUsingBiConsumerInForEach_thenConsumerExecutesForEachMapElement() {
Map<String, Integer> ages = new HashMap<>();
ages.put("John", 25);
ages.put("Freddy", 24);
ages.put("Samuel", 30);
ages.forEach((name, age) -> System.out.println(name + " is " + age + " years old"));
}
@Test
public void whenUsingPredicateInFilter_thenListValuesAreFilteredOut() {
List<String> names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David");
List<String> namesWithA = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
assertEquals(2, namesWithA.size());
assertTrue(namesWithA.contains("Angela"));
assertTrue(namesWithA.contains("Aaron"));
}
@Test
public void whenUsingUnaryOperatorWithReplaceAll_thenAllValuesInTheListAreReplaced() {
List<String> names = Arrays.asList("bob", "josh", "megan");
names.replaceAll(String::toUpperCase);
assertEquals("BOB", names.get(0));
assertEquals("JOSH", names.get(1));
assertEquals("MEGAN", names.get(2));
}
@Test
public void whenUsingBinaryOperatorWithStreamReduce_thenResultIsSumOfValues() {
List<Integer> values = Arrays.asList(3, 5, 8, 9, 12);
int sum = values.stream()
.reduce(0, (i1, i2) -> i1 + i2);
assertEquals(37, sum);
}
@Test
public void whenComposingTwoFunctions_thenFunctionsExecuteSequentially() {
Function<Integer, String> intToString = Object::toString;
Function<String, String> quote = s -> "'" + s + "'";
Function<Integer, String> quoteIntToString = quote.compose(intToString);
assertEquals("'5'", quoteIntToString.apply(5));
}
public double squareLazy(Supplier<Double> lazyValue) {
return Math.pow(lazyValue.get(), 2);
}
@Test
public void whenUsingSupplierToGenerateValue_thenValueIsGeneratedLazily() {
Supplier<Double> lazyValue = () -> {
Uninterruptibles.sleepUninterruptibly(1000, TimeUnit.MILLISECONDS);
return 9d;
};
double valueSquared = squareLazy(lazyValue);
assertEquals(81d, valueSquared, 0);
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.functionalinterface;
@FunctionalInterface
public interface ShortToByteFunction {
byte applyAsByte(short s);
}

View File

@ -0,0 +1,146 @@
package com.baeldung.threadpool;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class CoreThreadPoolTest {
@Test(timeout = 1000)
public void whenCallingExecuteWithRunnable_thenRunnableIsExecuted() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(1);
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
System.out.println("Hello World");
lock.countDown();
});
lock.await(1000, TimeUnit.MILLISECONDS);
}
@Test
public void whenUsingExecutorServiceAndFuture_thenCanWaitOnFutureResult() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<String> future = executorService.submit(() -> "Hello World");
String result = future.get();
assertEquals("Hello World", result);
}
@Test
public void whenUsingFixedThreadPool_thenCoreAndMaximumThreadSizeAreTheSame() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
assertEquals(2, executor.getPoolSize());
assertEquals(1, executor.getQueue().size());
}
@Test
public void whenUsingCachedThreadPool_thenPoolSizeGrowsUnbounded() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
executor.submit(() -> {
Thread.sleep(1000);
return null;
});
assertEquals(3, executor.getPoolSize());
assertEquals(0, executor.getQueue().size());
}
@Test(timeout = 1000)
public void whenUsingSingleThreadPool_thenTasksExecuteSequentially() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(2);
AtomicInteger counter = new AtomicInteger();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
counter.set(1);
lock.countDown();
});
executor.submit(() -> {
counter.compareAndSet(1, 2);
lock.countDown();
});
lock.await(1000, TimeUnit.MILLISECONDS);
assertEquals(2, counter.get());
}
@Test(timeout = 1000)
public void whenSchedulingTask_thenTaskExecutesWithinGivenPeriod() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(1);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
executor.schedule(() -> {
System.out.println("Hello World");
lock.countDown();
}, 500, TimeUnit.MILLISECONDS);
lock.await(1000, TimeUnit.MILLISECONDS);
}
@Test(timeout = 1000)
public void whenSchedulingTaskWithFixedPeriod_thenTaskExecutesMultipleTimes() throws InterruptedException {
CountDownLatch lock = new CountDownLatch(3);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
ScheduledFuture<?> future = executor.scheduleAtFixedRate(() -> {
System.out.println("Hello World");
lock.countDown();
}, 500, 100, TimeUnit.MILLISECONDS);
lock.await();
future.cancel(true);
}
@Test
public void whenUsingForkJoinPool_thenSumOfTreeElementsIsCalculatedCorrectly() {
TreeNode tree = new TreeNode(5,
new TreeNode(3), new TreeNode(2,
new TreeNode(2), new TreeNode(8)));
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
int sum = forkJoinPool.invoke(new CountingTask(tree));
assertEquals(20, sum);
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.threadpool;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class GuavaThreadPoolTest {
@Test
public void whenExecutingTaskWithDirectExecutor_thenTheTaskIsExecutedInTheCurrentThread() {
Executor executor = MoreExecutors.directExecutor();
AtomicBoolean executed = new AtomicBoolean();
executor.execute(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
executed.set(true);
});
assertTrue(executed.get());
}
@Test
public void whenJoiningFuturesWithAllAsList_thenCombinedFutureCompletesAfterAllFuturesComplete() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);
ListenableFuture<String> future1 = listeningExecutorService.submit(() -> "Hello");
ListenableFuture<String> future2 = listeningExecutorService.submit(() -> "World");
String greeting = Futures.allAsList(future1, future2).get()
.stream()
.collect(Collectors.joining(" "));
assertEquals("Hello World", greeting);
}
}

View File

@ -1,2 +0,0 @@
line 1
a second line

View File

@ -19,6 +19,7 @@ import java.io.Reader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardCopyOption;
import java.util.Scanner;
import org.apache.commons.io.FileUtils;
@ -191,6 +192,16 @@ public class JavaInputStreamToXUnitTest {
IOUtils.closeQuietly(outStream);
}
@Test
public final void givenUsingPlainJava8_whenConvertingAnInProgressInputStreamToAFile_thenCorrect() throws IOException {
final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt"));
final File targetFile = new File("src/main/resources/targetFile.tmp");
java.nio.file.Files.copy(initialStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
IOUtils.closeQuietly(initialStream);
}
@Test
public final void givenUsingGuava_whenConvertingAnInputStreamToAFile_thenCorrect() throws IOException {
final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt"));

View File

@ -1,5 +1,8 @@
package org.baeldung.java.io;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
@ -187,10 +190,24 @@ public class JavaReaderToXUnitTest {
targetStream.close();
}
@Test
public void givenUsingCommonsIO_whenConvertingReaderIntoInputStream_thenCorrect() throws IOException {
String initialString = "With Commons IO";
final Reader initialReader = new StringReader(initialString);
final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader));
final String finalString = IOUtils.toString(targetStream);
assertThat(finalString, equalTo(initialString));
initialReader.close();
targetStream.close();
}
// tests - Reader to InputStream with encoding
@Test
public void givenUsingPlainJava_whenConvertingReaderIntoInputStreamWithCharset_thenCorrect() throws IOException {
public void givenUsingPlainJava_whenConvertingReaderIntoInputStreamWithCharset() throws IOException {
final Reader initialReader = new StringReader("With Java");
final char[] charBuffer = new char[8 * 1024];
@ -225,4 +242,17 @@ public class JavaReaderToXUnitTest {
targetStream.close();
}
@Test
public void givenUsingCommonsIO_whenConvertingReaderIntoInputStreamWithEncoding_thenCorrect() throws IOException {
String initialString = "With Commons IO";
final Reader initialReader = new StringReader(initialString);
final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader), Charsets.UTF_8);
String finalString = IOUtils.toString(targetStream, Charsets.UTF_8);
assertThat(finalString, equalTo(initialString));
initialReader.close();
targetStream.close();
}
}

View File

@ -0,0 +1,66 @@
package org.baeldung.java.shell;
import org.junit.Assert;
import org.junit.Test;
import java.io.*;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
public class JavaProcessUnitTest {
private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows");
private static class StreamGobbler implements Runnable {
private InputStream inputStream;
private Consumer<String> consumer;
public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}
@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
}
}
private Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
Assert.assertNotNull(s);
}
};
private String homeDirectory = System.getProperty("user.home");
@Test
public void givenProcess_whenCreatingViaRuntime_shouldSucceed() throws Exception {
Process process;
if (IS_WINDOWS) {
process = Runtime.getRuntime().exec(String.format("cmd.exe /c dir %s", homeDirectory));
} else {
process = Runtime.getRuntime().exec(String.format("sh -c ls %s", homeDirectory));
}
StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
Executors.newSingleThreadExecutor().submit(streamGobbler);
int exitCode = process.waitFor();
Assert.assertEquals(0, exitCode);
}
@Test
public void givenProcess_whenCreatingViaProcessBuilder_shouldSucceed() throws Exception {
ProcessBuilder builder = new ProcessBuilder();
if (IS_WINDOWS) {
builder.command("cmd.exe", "/c", "dir");
} else {
builder.command("sh", "-c", "ls");
}
builder.directory(new File(homeDirectory));
Process process = builder.start();
StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
Executors.newSingleThreadExecutor().submit(streamGobbler);
int exitCode = process.waitFor();
Assert.assertEquals(0, exitCode);
}
}

Binary file not shown.

View File

@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[3.7.3.201602250914-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
</configs>
<autoconfigs>
</autoconfigs>
<configSets>
</configSets>
</beansProjectDescription>

233
couchbase-sdk-async/mvnw vendored Executable file
View File

@ -0,0 +1,233 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=`/usr/libexec/java_home`
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
local basedir=$(pwd)
local wdir=$(pwd)
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
wdir=$(cd "$wdir/.."; pwd)
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} "$@"

145
couchbase-sdk-async/mvnw.cmd vendored Normal file
View File

@ -0,0 +1,145 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
set MAVEN_CMD_LINE_ARGS=%*
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

102
couchbase-sdk-async/pom.xml Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>couchbase-sdk-async</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>couchbase-sdk-async</name>
<description>Couchbase SDK Asynchronous Operations</description>
<dependencies>
<!-- Couchbase SDK -->
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>java-client</artifactId>
<version>${couchbase.client.version}</version>
</dependency>
<!-- Spring Context for Dependency Injection -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<!-- Test-Scoped Dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.7</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<couchbase.client.version>2.2.6</couchbase.client.version>
<spring-framework.version>4.2.4.RELEASE</spring-framework.version>
<logback.version>1.1.3</logback.version>
<org.slf4j.version>1.7.12</org.slf4j.version>
<junit.version>4.11</junit.version>
<commons-lang3.version>3.4</commons-lang3.version>
</properties>
</project>

View File

@ -0,0 +1,89 @@
package com.baeldung.couchbase.person;
import com.baeldung.couchbase.service.CouchbaseEntity;
public class Person implements CouchbaseEntity {
private String id;
private String type;
private String name;
private String homeTown;
Person() {}
public Person(Builder b) {
this.id = b.id;
this.type = b.type;
this.name = b.name;
this.homeTown = b.homeTown;
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHomeTown() {
return homeTown;
}
public void setHomeTown(String homeTown) {
this.homeTown = homeTown;
}
public static class Builder {
private String id;
private String type;
private String name;
private String homeTown;
public static Builder newInstance() {
return new Builder();
}
public Person build() {
return new Person(this);
}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder type(String type) {
this.type = type;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder homeTown(String homeTown) {
this.homeTown = homeTown;
return this;
}
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.couchbase.person;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.baeldung.couchbase.service.AbstractCrudService;
import com.baeldung.couchbase.service.BucketService;
@Service
public class PersonCrudService extends AbstractCrudService<Person> {
@Autowired
public PersonCrudService(
@Qualifier("TutorialBucketService") BucketService bucketService,
PersonDocumentConverter converter) {
super(bucketService, converter);
}
@PostConstruct
private void init() {
loadBucket();
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.couchbase.person;
import org.springframework.stereotype.Service;
import com.baeldung.couchbase.service.JsonDocumentConverter;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonObject;
@Service
public class PersonDocumentConverter implements JsonDocumentConverter<Person> {
@Override
public JsonDocument toDocument(Person p) {
JsonObject content = JsonObject.empty()
.put("type", "Person")
.put("name", p.getName())
.put("homeTown", p.getHomeTown());
return JsonDocument.create(p.getId(), content);
}
@Override
public Person fromDocument(JsonDocument doc) {
JsonObject content = doc.content();
Person p = new Person();
p.setId(doc.id());
p.setType("Person");
p.setName(content.getString("name"));
p.setHomeTown(content.getString("homeTown"));
return p;
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.couchbase.person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.couchbase.client.core.CouchbaseException;
@Service
public class RegistrationService {
@Autowired
private PersonCrudService crud;
public void registerNewPerson(String name, String homeTown) {
Person person = new Person();
person.setName(name);
person.setHomeTown(homeTown);
crud.create(person);
}
public Person findRegistrant(String id) {
try{
return crud.read(id);
}
catch(CouchbaseException e) {
return crud.readFromReplica(id);
}
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.couchbase.service;
import com.couchbase.client.java.Bucket;
public abstract class AbstractBucketService implements BucketService {
private ClusterService clusterService;
private Bucket bucket;
protected void openBucket() {
bucket = clusterService.openBucket(getBucketName(), getBucketPassword());
}
protected abstract String getBucketName();
protected abstract String getBucketPassword();
public AbstractBucketService(ClusterService clusterService) {
this.clusterService = clusterService;
}
@Override
public Bucket getBucket() {
return bucket;
}
}

View File

@ -0,0 +1,174 @@
package com.baeldung.couchbase.service;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.couchbase.client.core.BackpressureException;
import com.couchbase.client.core.time.Delay;
import com.couchbase.client.java.AsyncBucket;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.ReplicaMode;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.util.retry.RetryBuilder;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
public abstract class AbstractCrudService<T extends CouchbaseEntity> implements CrudService<T> {
private static final Logger logger = LoggerFactory.getLogger(AbstractCrudService.class);
private BucketService bucketService;
private Bucket bucket;
private JsonDocumentConverter<T> converter;
public AbstractCrudService(BucketService bucketService, JsonDocumentConverter<T> converter) {
this.bucketService = bucketService;
this.converter = converter;
}
protected void loadBucket() {
bucket = bucketService.getBucket();
}
@Override
public void create(T t) {
if(t.getId() == null) {
t.setId(UUID.randomUUID().toString());
}
JsonDocument doc = converter.toDocument(t);
bucket.insert(doc);
}
@Override
public T read(String id) {
JsonDocument doc = bucket.get(id);
return (doc == null ? null : converter.fromDocument(doc));
}
@Override
public T readFromReplica(String id) {
List<JsonDocument> docs = bucket.getFromReplica(id, ReplicaMode.FIRST);
return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0)));
}
@Override
public void update(T t) {
JsonDocument doc = converter.toDocument(t);
bucket.upsert(doc);
}
@Override
public void delete(String id) {
bucket.remove(id);
}
@Override
public List<T> readBulk(Iterable<String> ids) {
final AsyncBucket asyncBucket = bucket.async();
Observable<JsonDocument> asyncOperation = Observable
.from(ids)
.flatMap(new Func1<String, Observable<JsonDocument>>() {
public Observable<JsonDocument> call(String key) {
return asyncBucket.get(key);
}
});
final List<T> items = new ArrayList<T>();
try {
asyncOperation.toBlocking()
.forEach(new Action1<JsonDocument>() {
public void call(JsonDocument doc) {
T item = converter.fromDocument(doc);
items.add(item);
}
});
} catch (Exception e) {
logger.error("Error during bulk get", e);
}
return items;
}
@Override
public void createBulk(Iterable<T> items) {
final AsyncBucket asyncBucket = bucket.async();
Observable
.from(items)
.flatMap(new Func1<T, Observable<JsonDocument>>() {
@SuppressWarnings("unchecked")
@Override
public Observable<JsonDocument> call(final T t) {
if(t.getId() == null) {
t.setId(UUID.randomUUID().toString());
}
JsonDocument doc = converter.toDocument(t);
return asyncBucket.insert(doc)
.retryWhen(RetryBuilder
.anyOf(BackpressureException.class)
.delay(Delay.exponential(TimeUnit.MILLISECONDS, 100))
.max(10)
.build());
}
})
.last()
.toBlocking()
.single();
}
@Override
public void updateBulk(Iterable<T> items) {
final AsyncBucket asyncBucket = bucket.async();
Observable
.from(items)
.flatMap(new Func1<T, Observable<JsonDocument>>() {
@SuppressWarnings("unchecked")
@Override
public Observable<JsonDocument> call(final T t) {
JsonDocument doc = converter.toDocument(t);
return asyncBucket.upsert(doc)
.retryWhen(RetryBuilder
.anyOf(BackpressureException.class)
.delay(Delay.exponential(TimeUnit.MILLISECONDS, 100))
.max(10)
.build());
}
})
.last()
.toBlocking()
.single();
}
@Override
public void deleteBulk(Iterable<String> ids) {
final AsyncBucket asyncBucket = bucket.async();
Observable
.from(ids)
.flatMap(new Func1<String, Observable<JsonDocument>>() {
@SuppressWarnings("unchecked")
@Override
public Observable<JsonDocument> call(String key) {
return asyncBucket.remove(key)
.retryWhen(RetryBuilder
.anyOf(BackpressureException.class)
.delay(Delay.exponential(TimeUnit.MILLISECONDS, 100))
.max(10)
.build());
}
})
.last()
.toBlocking()
.single();
}
@Override
public boolean exists(String id) {
return bucket.exists(id);
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.couchbase.service;
import com.couchbase.client.java.Bucket;
public interface BucketService {
Bucket getBucket();
}

View File

@ -0,0 +1,8 @@
package com.baeldung.couchbase.service;
import com.couchbase.client.java.Bucket;
public interface ClusterService {
Bucket openBucket(String name, String password);
}

View File

@ -0,0 +1,36 @@
package com.baeldung.couchbase.service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Service;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
@Service
public class ClusterServiceImpl implements ClusterService {
private Cluster cluster;
private Map<String, Bucket> buckets = new ConcurrentHashMap<>();
@PostConstruct
private void init() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create();
cluster = CouchbaseCluster.create(env, "localhost");
}
@Override
synchronized public Bucket openBucket(String name, String password) {
if(!buckets.containsKey(name)) {
Bucket bucket = cluster.openBucket(name, password);
buckets.put(name, bucket);
}
return buckets.get(name);
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.couchbase.service;
public interface CouchbaseEntity {
String getId();
void setId(String id);
}

View File

@ -0,0 +1,26 @@
package com.baeldung.couchbase.service;
import java.util.List;
public interface CrudService<T> {
void create(T t);
T read(String id);
T readFromReplica(String id);
void update(T t);
void delete(String id);
List<T> readBulk(Iterable<String> ids);
void createBulk(Iterable<T> items);
void updateBulk(Iterable<T> items);
void deleteBulk(Iterable<String> ids);
boolean exists(String id);
}

View File

@ -0,0 +1,10 @@
package com.baeldung.couchbase.service;
import com.couchbase.client.java.document.JsonDocument;
public interface JsonDocumentConverter<T> {
JsonDocument toDocument(T t);
T fromDocument(JsonDocument doc);
}

View File

@ -0,0 +1,32 @@
package com.baeldung.couchbase.service;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
@Qualifier("TutorialBucketService")
public class TutorialBucketService extends AbstractBucketService {
@PostConstruct
void init() {
openBucket();
}
@Autowired
public TutorialBucketService(ClusterService clusterService) {
super(clusterService);
}
@Override
protected String getBucketName() {
return "baeldung-tutorial";
}
@Override
protected String getBucketPassword() {
return "";
}
}

View File

@ -0,0 +1,17 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="com.baeldung" level="DEBUG" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,13 @@
package com.baeldung.couchbase;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { IntegrationTestConfig.class })
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
public abstract class IntegrationTest {
}

View File

@ -0,0 +1,9 @@
package com.baeldung.couchbase;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages={"com.baeldung.couchbase"})
public class IntegrationTestConfig {
}

View File

@ -0,0 +1,220 @@
package com.baeldung.couchbase.person;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.baeldung.couchbase.IntegrationTest;
import com.baeldung.couchbase.service.BucketService;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.document.JsonDocument;
public class PersonCrudServiceTest extends IntegrationTest {
@Autowired
private PersonCrudService personService;
@Autowired
@Qualifier("TutorialBucketService")
private BucketService bucketService;
@Autowired
private PersonDocumentConverter converter;
private Bucket bucket;
@PostConstruct
private void init() {
bucket = bucketService.getBucket();
}
@Test
public final void givenRandomPerson_whenCreate_thenPersonPersisted() {
//create person
Person person = randomPerson();
personService.create(person);
//check results
assertNotNull(person.getId());
assertNotNull(bucket.get(person.getId()));
//cleanup
bucket.remove(person.getId());
}
@Test
public final void givenId_whenRead_thenReturnsPerson() {
//create and insert person document
String id = insertRandomPersonDocument().id();
//read person and check results
assertNotNull(personService.read(id));
//cleanup
bucket.remove(id);
}
@Test
public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() {
//create and insert person document
JsonDocument doc = insertRandomPersonDocument();
//update person
Person expected = converter.fromDocument(doc);
String updatedHomeTown = RandomStringUtils.randomAlphabetic(12);
expected.setHomeTown(updatedHomeTown);
personService.update(expected);
//check results
JsonDocument actual = bucket.get(expected.getId());
assertNotNull(actual);
assertNotNull(actual.content());
assertEquals(expected.getHomeTown(), actual.content().getString("homeTown"));
//cleanup
bucket.remove(expected.getId());
}
@Test
public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() {
//create and insert person document
String id = insertRandomPersonDocument().id();
//delete person and check results
personService.delete(id);
assertNull(bucket.get(id));
}
@Test
public final void givenIds_whenReadBulk_thenReturnsOnlyPersonsWithMatchingIds() {
List<String> ids = new ArrayList<>();
//add some person documents
for(int i=0; i<5; i++) {
ids.add(insertRandomPersonDocument().id());
}
//perform bulk read
List<Person> persons = personService.readBulk(ids);
//check results
for(Person person : persons) {
assertTrue(ids.contains(person.getId()));
}
//cleanup
for(String id : ids) {
bucket.remove(id);
}
}
@Test
public final void givenPersons_whenInsertBulk_thenPersonsAreInserted() {
//create some persons
List<Person> persons = new ArrayList<>();
for(int i=0; i<5; i++) {
persons.add(randomPerson());
}
//perform bulk insert
personService.createBulk(persons);
//check results
for(Person person : persons) {
assertNotNull(bucket.get(person.getId()));
}
//cleanup
for(Person person : persons) {
bucket.remove(person.getId());
}
}
@Test
public final void givenPersons_whenUpdateBulk_thenPersonsAreUpdated() {
List<String> ids = new ArrayList<>();
//add some person documents
for(int i=0; i<5; i++) {
ids.add(insertRandomPersonDocument().id());
}
//load persons from Couchbase
List<Person> persons = new ArrayList<>();
for(String id : ids) {
persons.add(converter.fromDocument(bucket.get(id)));
}
//modify persons
for(Person person : persons) {
person.setHomeTown(RandomStringUtils.randomAlphabetic(10));
}
//perform bulk update
personService.updateBulk(persons);
//check results
for(Person person : persons) {
JsonDocument doc = bucket.get(person.getId());
assertEquals(person.getName(), doc.content().getString("name"));
assertEquals(person.getHomeTown(), doc.content().getString("homeTown"));
}
//cleanup
for(String id : ids) {
bucket.remove(id);
}
}
@Test
public void givenIds_whenDeleteBulk_thenPersonsAreDeleted() {
List<String> ids = new ArrayList<>();
//add some person documents
for(int i=0; i<5; i++) {
ids.add(insertRandomPersonDocument().id());
}
//perform bulk delete
personService.deleteBulk(ids);
//check results
for(String id : ids) {
assertNull(bucket.get(id));
}
}
private JsonDocument insertRandomPersonDocument() {
Person expected = randomPersonWithId();
JsonDocument doc = converter.toDocument(expected);
return bucket.insert(doc);
}
private Person randomPerson() {
return Person.Builder.newInstance()
.name(RandomStringUtils.randomAlphabetic(10))
.homeTown(RandomStringUtils.randomAlphabetic(10))
.build();
}
private Person randomPersonWithId() {
return Person.Builder.newInstance()
.id(UUID.randomUUID().toString())
.name(RandomStringUtils.randomAlphabetic(10))
.homeTown(RandomStringUtils.randomAlphabetic(10))
.build();
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.couchbase.service;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import com.baeldung.couchbase.IntegrationTest;
import com.baeldung.couchbase.IntegrationTestConfig;
import com.couchbase.client.java.Bucket;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { IntegrationTestConfig.class })
@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
public class ClusterServiceTest extends IntegrationTest {
@Autowired
private ClusterService couchbaseService;
private Bucket defaultBucket;
@Test
public void whenOpenBucket_thenBucketIsNotNull() throws Exception {
defaultBucket = couchbaseService.openBucket("default", "");
assertNotNull(defaultBucket);
assertFalse(defaultBucket.isClosed());
defaultBucket.close();
}
}

3
deltaspike/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.idea
baeldung-jee7-seed.iml
/target

301
deltaspike/pom.xml Normal file
View File

@ -0,0 +1,301 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>deltaspike</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>deltaspike</name>
<description>A starter Java EE 7 webapp which uses DeltaSpike</description>
<url>http://wildfly.org</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<distribution>repo</distribution>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<properties>
<!-- Explicitly declaring the source encoding eliminates the following
message: -->
<!-- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered
resources, i.e. build is platform dependent! -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- JBoss dependency versions -->
<version.wildfly.maven.plugin>1.0.2.Final</version.wildfly.maven.plugin>
<!-- Define the version of the JBoss BOMs we want to import to specify
tested stacks. -->
<version.jboss.bom>8.2.1.Final</version.jboss.bom>
<!-- other plugin versions -->
<version.compiler.plugin>3.1</version.compiler.plugin>
<version.surefire.plugin>2.16</version.surefire.plugin>
<version.war.plugin>2.5</version.war.plugin>
<!-- maven-compiler-plugin -->
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
</properties>
<dependencyManagement>
<dependencies>
<!-- JBoss distributes a complete set of Java EE 7 APIs including a Bill
of Materials (BOM). A BOM specifies the versions of a "stack" (or a collection)
of artifacts. We use this here so that we always get the correct versions
of artifacts. Here we use the jboss-javaee-7.0-with-tools stack (you can
read this as the JBoss stack of the Java EE 7 APIs, with some extras tools
for your project, such as Arquillian for testing) and the jboss-javaee-7.0-with-hibernate
stack you can read this as the JBoss stack of the Java EE 7 APIs, with extras
from the Hibernate family of projects) -->
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>jboss-javaee-7.0-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>jboss-javaee-7.0-with-hibernate</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- First declare the APIs we depend on and need for compilation. All
of them are provided by JBoss WildFly -->
<!-- Import the CDI API, we use provided scope as the API is included in
JBoss WildFly -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the Common Annotations API (JSR-250), we use provided scope
as the API is included in JBoss WildFly -->
<dependency>
<groupId>org.jboss.spec.javax.annotation</groupId>
<artifactId>jboss-annotations-api_1.2_spec</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the JAX-RS API, we use provided scope as the API is included
in JBoss WildFly -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the JPA API, we use provided scope as the API is included in
JBoss WildFly -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the EJB API, we use provided scope as the API is included in
JBoss WildFly -->
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSR-303 (Bean Validation) Implementation -->
<!-- Provides portable constraints such as @Email -->
<!-- Hibernate Validator is shipped in JBoss WildFly -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Import the JSF API, we use provided scope as the API is included in
JBoss WildFly -->
<dependency>
<groupId>org.jboss.spec.javax.faces</groupId>
<artifactId>jboss-jsf-api_2.2_spec</artifactId>
<scope>provided</scope>
</dependency>
<!-- Now we declare any tools needed -->
<!-- Annotation processor to generate the JPA 2.0 metamodel classes for
typesafe criteria queries -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>provided</scope>
</dependency>
<!-- Annotation processor that raising compilation errors whenever constraint
annotations are incorrectly used. -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<scope>provided</scope>
</dependency>
<!-- Needed for running tests (you may also use TestNG) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Optional, but highly recommended -->
<!-- Arquillian allows you to test enterprise code such as EJBs and Transactional(JTA)
JPA from JUnit/TestNG -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.modules</groupId>
<artifactId>deltaspike-data-module-api</artifactId>
<version>1.7.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.modules</groupId>
<artifactId>deltaspike-data-module-impl</artifactId>
<version>1.7.1</version>
<scope>runtime</scope>
</dependency>
<!-- querydsl libraries -->
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>3.7.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>3.7.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
<build>
<!-- Maven will append the version to the finalName (which is the name
given to the generated war, and hence the context root) -->
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${version.war.plugin}</version>
<configuration>
<!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.0.9</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<!-- The WildFly plugin deploys your war to a local WildFly container -->
<!-- To use, run: mvn package wildfly:deploy -->
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.maven.plugin}</version>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- The default profile skips all tests, though you can tune it to run
just unit tests based on a custom pattern -->
<!-- Seperate profiles are provided for running all tests, including Arquillian
tests that execute in the specified container -->
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.surefire.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<!-- An optional Arquillian testing profile that executes tests
in your WildFly instance -->
<!-- This profile will start a new WildFly instance, and execute the
test, shutting it down when done -->
<!-- Run with: mvn clean test -Parq-wildfly-managed -->
<id>arq-wildfly-managed</id>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,84 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.controller;
import javax.annotation.PostConstruct;
import javax.enterprise.inject.Model;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import baeldung.model.Member;
import baeldung.service.MemberRegistration;
// The @Model stereotype is a convenience mechanism to make this a request-scoped bean that has an
// EL name
// Read more about the @Model stereotype in this FAQ:
// http://www.cdi-spec.org/faq/#accordion6
@Model
public class MemberController {
@Inject
private FacesContext facesContext;
@Inject
private MemberRegistration memberRegistration;
@Produces
@Named
private Member newMember;
@PostConstruct
public void initNewMember() {
newMember = new Member();
}
public void register() throws Exception {
try {
memberRegistration.register(newMember);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_INFO, "Registered!", "Registration successful");
facesContext.addMessage(null, m);
initNewMember();
} catch (Exception e) {
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Registration unsuccessful");
facesContext.addMessage(null, m);
}
}
private String getRootErrorMessage(Exception e) {
// Default to general error message that registration failed.
String errorMessage = "Registration failed. See server log for more information";
if (e == null) {
// This shouldn't happen, but return the default messages
return errorMessage;
}
// Start with the exception and recurse to find the root cause
Throwable t = e;
while (t != null) {
// Get the message from the Throwable class instance
errorMessage = t.getLocalizedMessage();
t = t.getCause();
}
// This is the root cause message
return errorMessage;
}
}

View File

@ -0,0 +1,29 @@
package baeldung.data;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
@ApplicationScoped
public class EntityManagerProducer {
@PersistenceUnit(unitName = "primary")
private EntityManagerFactory entityManagerFactory;
@Produces
@Default
@RequestScoped
public EntityManager create() {
return this.entityManagerFactory.createEntityManager();
}
public void dispose(@Disposes @Default EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
}

View File

@ -0,0 +1,54 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.data;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;
import baeldung.model.Member;
@RequestScoped
public class MemberListProducer {
@Inject
private MemberRepository memberRepository;
private List<Member> members;
// @Named provides access the return value via the EL variable name "members" in the UI (e.g.
// Facelets or JSP view)
@Produces
@Named
public List<Member> getMembers() {
return members;
}
public void onMemberListChanged(@Observes(notifyObserver = Reception.IF_EXISTS) final Member member) {
retrieveAllMembersOrderedByName();
}
@PostConstruct
public void retrieveAllMembersOrderedByName() {
members = memberRepository.findAllOrderedByNameWithQueryDSL();
}
}

View File

@ -0,0 +1,43 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.data;
import baeldung.model.Member;
import baeldung.model.QMember;
import org.apache.deltaspike.data.api.*;
import java.util.List;
@Repository
@EntityManagerConfig(entityManagerResolver = SecondaryEntityManagerResolver.class)
public abstract class MemberRepository extends AbstractEntityRepository<Member, Long> implements QueryDslSupport {
public abstract Member findById(Long id);
public abstract Member findByEmail(String email);
@Query("from Member m order by m.name")
public abstract List<Member> findAllOrderedByName();
public List<Member> findAllOrderedByNameWithQueryDSL() {
final QMember member = QMember.member;
return jpaQuery()
.from(member)
.orderBy(member.email.asc())
.list(member);
}
}

View File

@ -0,0 +1,18 @@
package baeldung.data;
import com.mysema.query.jpa.impl.JPAQuery;
import org.apache.deltaspike.data.spi.DelegateQueryHandler;
import org.apache.deltaspike.data.spi.QueryInvocationContext;
import javax.inject.Inject;
public class QueryDslRepositoryExtension<E> implements QueryDslSupport, DelegateQueryHandler {
@Inject
private QueryInvocationContext context;
@Override
public JPAQuery jpaQuery() {
return new JPAQuery(context.getEntityManager());
}
}

View File

@ -0,0 +1,7 @@
package baeldung.data;
import com.mysema.query.jpa.impl.JPAQuery;
public interface QueryDslSupport {
JPAQuery jpaQuery();
}

View File

@ -0,0 +1,30 @@
package baeldung.data;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
@ApplicationScoped
public class SecondaryEntityManagerProducer {
@PersistenceUnit(unitName = "secondary")
private EntityManagerFactory entityManagerFactory;
@Produces
@Default
@RequestScoped
@SecondaryPersistenceUnit
public EntityManager create() {
return this.entityManagerFactory.createEntityManager();
}
public void dispose(@Disposes @Default EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
}

View File

@ -0,0 +1,18 @@
package baeldung.data;
import org.apache.deltaspike.data.api.EntityManagerResolver;
import javax.inject.Inject;
import javax.persistence.EntityManager;
public class SecondaryEntityManagerResolver implements EntityManagerResolver {
@Inject
@SecondaryPersistenceUnit
private EntityManager entityManager;
@Override
public EntityManager resolveEntityManager() {
return entityManager;
}
}

View File

@ -0,0 +1,12 @@
package baeldung.data;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface SecondaryPersistenceUnit {
}

View File

@ -0,0 +1,93 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
@SuppressWarnings("serial")
@Entity
@XmlRootElement
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class Member implements Serializable {
@Id
@GeneratedValue
private Long id;
@NotNull
@Size(min = 1, max = 25)
@Pattern(regexp = "[^0-9]*", message = "Must not contain numbers")
private String name;
@NotNull
@NotEmpty
@Email
private String email;
@NotNull
@Size(min = 10, max = 12)
@Digits(fraction = 0, integer = 12)
@Column(name = "phone_number")
private String phoneNumber;
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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}

View File

@ -0,0 +1,33 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.rest;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
/**
* A class extending {@link Application} and annotated with @ApplicationPath is the Java EE 7 "no XML" approach to activating
* JAX-RS.
* <p>
* <p>
* Resources are served relative to the servlet path specified in the {@link ApplicationPath} annotation.
* </p>
*/
@ApplicationPath("/rest")
public class JaxRsActivator extends Application {
/* class body intentionally left blank */
}

View File

@ -0,0 +1,185 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.rest;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.NoResultException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import baeldung.data.MemberRepository;
import baeldung.model.Member;
import baeldung.service.MemberRegistration;
/**
* JAX-RS Example
* <p/>
* This class produces a RESTful service to read/write the contents of the members table.
*/
@Path("/members")
@RequestScoped
public class MemberResourceRESTService {
@Inject
private Logger log;
@Inject
private Validator validator;
@Inject
private MemberRepository repository;
@Inject
MemberRegistration registration;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Member> listAllMembers() {
return repository.findAllOrderedByName();
}
@GET
@Path("/{id:[0-9][0-9]*}")
@Produces(MediaType.APPLICATION_JSON)
public Member lookupMemberById(@PathParam("id") long id) {
Member member = repository.findById(id);
if (member == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return member;
}
/**
* Creates a new member from the values provided. Performs validation, and will return a JAX-RS response with either 200 ok,
* or with a map of fields, and related errors.
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createMember(Member member) {
Response.ResponseBuilder builder = null;
try {
// Validates member using bean validation
validateMember(member);
registration.register(member);
// Create an "ok" response
builder = Response.ok();
} catch (ConstraintViolationException ce) {
// Handle bean validation issues
builder = createViolationResponse(ce.getConstraintViolations());
} catch (ValidationException e) {
// Handle the unique constrain violation
Map<String, String> responseObj = new HashMap<>();
responseObj.put("email", "Email taken");
builder = Response.status(Response.Status.CONFLICT).entity(responseObj);
} catch (Exception e) {
// Handle generic exceptions
Map<String, String> responseObj = new HashMap<>();
responseObj.put("error", e.getMessage());
builder = Response.status(Response.Status.BAD_REQUEST).entity(responseObj);
}
return builder.build();
}
/**
* <p>
* Validates the given Member variable and throws validation exceptions based on the type of error. If the error is standard
* bean validation errors then it will throw a ConstraintValidationException with the set of the constraints violated.
* </p>
* <p>
* If the error is caused because an existing member with the same email is registered it throws a regular validation
* exception so that it can be interpreted separately.
* </p>
*
* @param member Member to be validated
* @throws ConstraintViolationException If Bean Validation errors exist
* @throws ValidationException If member with the same email already exists
*/
private void validateMember(Member member) throws ConstraintViolationException, ValidationException {
// Create a bean validator and check for issues.
Set<ConstraintViolation<Member>> violations = validator.validate(member);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(violations));
}
// Check the uniqueness of the email address
if (emailAlreadyExists(member.getEmail())) {
throw new ValidationException("Unique Email Violation");
}
}
/**
* Creates a JAX-RS "Bad Request" response including a map of all violation fields, and their message. This can then be used
* by clients to show violations.
*
* @param violations A set of violations that needs to be reported
* @return JAX-RS response containing all violations
*/
private Response.ResponseBuilder createViolationResponse(Set<ConstraintViolation<?>> violations) {
log.fine("Validation completed. violations found: " + violations.size());
Map<String, String> responseObj = new HashMap<>();
for (ConstraintViolation<?> violation : violations) {
responseObj.put(violation.getPropertyPath().toString(), violation.getMessage());
}
return Response.status(Response.Status.BAD_REQUEST).entity(responseObj);
}
/**
* Checks if a member with the same email address is already registered. This is the only way to easily capture the
* "@UniqueConstraint(columnNames = "email")" constraint from the Member class.
*
* @param email The email to check
* @return True if the email already exists, and false otherwise
*/
public boolean emailAlreadyExists(String email) {
Member member = null;
try {
member = repository.findByEmail(email);
} catch (NoResultException e) {
// ignore
}
return member != null;
}
}

View File

@ -0,0 +1,85 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.service;
import baeldung.data.MemberRepository;
import baeldung.data.SecondaryPersistenceUnit;
import baeldung.model.Member;
import baeldung.model.QMember;
import javax.ejb.Stateless;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Default;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import javax.validation.Validator;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
@Stateless
public class MemberRegistration {
@Inject
private Logger log;
@Inject
private MemberRepository repository;
@Inject
private Event<Member> memberEventSrc;
@Inject
private Validator validator;
private void validateMember(Member member) throws ConstraintViolationException, ValidationException {
// Create a bean validator and check for issues.
Set<ConstraintViolation<Member>> violations = validator.validate(member);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(violations));
}
// Check the uniqueness of the email address
if (emailAlreadyExists(member.getEmail())) {
throw new ValidationException("Unique Email Violation");
}
}
public void register(Member member) throws Exception {
log.info("Registering " + member.getName());
validateMember(member);
repository.save(member);
memberEventSrc.fire(member);
}
public boolean emailAlreadyExists(String email) {
Member member = null;
try {
member = repository.findByEmail(email);
} catch (NoResultException e) {
// ignore
}
return member != null;
}
}

View File

@ -0,0 +1,53 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.util;
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
/**
* This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans
* <p>
* <p>
* Example injection on a managed bean field:
* </p>
* <p>
* <pre>
* &#064;Inject
* private EntityManager em;
* </pre>
*/
public class Resources {
@Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
@Produces
@RequestScoped
public FacesContext produceFacesContext() {
return FacesContext.getCurrentInstance();
}
}

View File

@ -0,0 +1 @@
globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="primary" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/baeldung-jee7-seedDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
<persistence-unit name="secondary" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/baeldung-jee7-seed-secondaryDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,19 @@
--
-- JBoss, Home of Professional Open Source
-- Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
-- contributors by the @authors tag. See the copyright.txt in the
-- distribution for a full listing of individual contributors.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
-- http://www.apache.org/licenses/LICENSE-2.0
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- You can use this file to load seed data into the database using SQL statements
insert into Member (id, name, email, phone_number) values (0, 'John Smith', 'john.smith@mailinator.com', '2125551212')

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- This is an unmanaged datasource. It should be used for proofs of concept
or testing only. It uses H2, an in memory database that ships with JBoss
AS. -->
<datasources xmlns="http://www.jboss.org/ironjacamar/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd">
<!-- The datasource is bound into JNDI at this location. We reference
this in META-INF/persistence.xml -->
<datasource jndi-name="java:jboss/datasources/baeldung-jee7-seedDS"
pool-name="baeldung-jee7-seed" enabled="true"
use-java-context="true">
<connection-url>jdbc:h2:mem:baeldung-jee7-seed;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
</datasources>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<datasources xmlns="http://www.jboss.org/ironjacamar/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd">
<!-- The datasource is bound into JNDI at this location. We reference
this in META-INF/persistence.xml -->
<datasource jndi-name="java:jboss/datasources/baeldung-jee7-seed-secondaryDS"
pool-name="baeldung-jee7-seed" enabled="true"
use-java-context="true">
<connection-url>jdbc:h2:mem:baeldung-jee7-seed;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
</datasources>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Marker file indicating CDI should be enabled -->
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
</beans>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Marker file indicating JSF 2.2 should be enabled in the application -->
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
</faces-config>

View File

@ -0,0 +1,55 @@
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>baeldung-jee7-seed</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<h:outputStylesheet name="css/screen.css" />
</h:head>
<h:body>
<div id="container">
<div class="dualbrand">
<img src="resources/gfx/dualbrand_logo.png" />
</div>
<div id="content">
<ui:insert name="content">
[Template content will be inserted here]
</ui:insert>
</div>
<div id="aside">
<p>Learn more about JBoss WildFly.</p>
<ul>
<li><a
href="https://github.com/wildfly/quickstart/blob/master/guide/Introduction.asciidoc">Getting
Started Developing Applications Guide</a></li>
<li><a href="http://www.wildfly.org/">Community
Project Information</a></li>
</ul>
</div>
<div id="footer">
<p>
This project was generated from a Maven archetype from
WildFly.<br />
</p>
</div>
</div>
</h:body>
</html>

View File

@ -0,0 +1,23 @@
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Plain HTML page that kicks us into the app -->
<html>
<head>
<meta http-equiv="Refresh" content="0; URL=index.jsf">
</head>
</html>

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
template="/WEB-INF/templates/default.xhtml">
<ui:define name="content">
<h1>Welcome to WildFly!</h1>
<div>
<p>You have successfully deployed a Java EE 7 Enterprise
Application.</p>
<h3>Your application can run on:</h3>
<img src="resources/gfx/wildfly_400x130.jpg" />
</div>
<h:form id="reg">
<h2>Member Registration</h2>
<p>Enforces annotation-based constraints defined on the
model class.</p>
<h:panelGrid columns="3" columnClasses="titleCell">
<h:outputLabel for="name" value="Name:" />
<h:inputText id="name" value="#{newMember.name}" />
<h:message for="name" errorClass="invalid" />
<h:outputLabel for="email" value="Email:" />
<h:inputText id="email" value="#{newMember.email}" />
<h:message for="email" errorClass="invalid" />
<h:outputLabel for="phoneNumber" value="Phone #:" />
<h:inputText id="phoneNumber"
value="#{newMember.phoneNumber}" />
<h:message for="phoneNumber" errorClass="invalid" />
</h:panelGrid>
<p>
<h:panelGrid columns="2">
<h:commandButton id="register"
action="#{memberController.register}"
value="Register" styleClass="register" />
<h:messages styleClass="messages"
errorClass="invalid" infoClass="valid"
warnClass="warning" globalOnly="true" />
</h:panelGrid>
</p>
</h:form>
<h2>Members</h2>
<h:panelGroup rendered="#{empty members}">
<em>No registered members.</em>
</h:panelGroup>
<h:dataTable var="_member" value="#{members}"
rendered="#{not empty members}"
styleClass="simpletablestyle">
<h:column>
<f:facet name="header">Id</f:facet>
#{_member.id}
</h:column>
<h:column>
<f:facet name="header">Name</f:facet>
#{_member.name}
</h:column>
<h:column>
<f:facet name="header">Email</f:facet>
#{_member.email}
</h:column>
<h:column>
<f:facet name="header">Phone #</f:facet>
#{_member.phoneNumber}
</h:column>
<h:column>
<f:facet name="header">REST URL</f:facet>
<a
href="#{request.contextPath}/rest/members/#{_member.id}">/rest/members/#{_member.id}</a>
</h:column>
<f:facet name="footer">
REST URL for all members: <a
href="#{request.contextPath}/rest/members">/rest/members</a>
</f:facet>
</h:dataTable>
</ui:define>
</ui:composition>

View File

@ -0,0 +1,202 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Core styles for the page */
body {
margin: 0;
padding: 0;
background-color: #F1F1F1;
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 0.8em;
color:#363636;
}
#container {
margin: 0 auto;
padding: 0 20px 10px 20px;
border-top: 5px solid #000000;
border-left: 5px solid #8c8f91;
border-right: 5px solid #8c8f91;
border-bottom: 25px solid #8c8f91;
width: 865px; /* subtract 40px from banner width for padding */
background: #FFFFFF;
background-image: url(#{request.contextPath}/resources/gfx/headerbkg.png);
background-repeat: repeat-x;
padding-top: 30px;
box-shadow: 3px 3px 15px #d5d5d5;
}
#content {
float: left;
width: 500px;
margin: 20px;
}
#aside {
font-size: 0.9em;
width: 275px;
float: left;
margin: 20px 0px;
border: 1px solid #D5D5D5;
background: #F1F1F1;
background-image: url(#{request.contextPath}/resources/gfx/asidebkg.png);
background-repeat: repeat-x;
padding: 20px;
}
#aside ul {
padding-left: 30px;
}
.dualbrand {
float: right;
padding-right: 10px;
}
#footer {
clear: both;
text-align: center;
color: #666666;
font-size: 0.85em;
}
code {
font-size: 1.1em;
}
a {
color: #4a5d75;
text-decoration: none;
}
a:hover {
color: #369;
text-decoration: underline;
}
h1 {
color:#243446;
font-size: 2.25em;
}
h2 {
font-size: 1em;
}
h3 {
color:#243446;
}
h4 {
}
h5 {
}
h6 {
}
/* Member registration styles */
span.invalid {
padding-left: 3px;
color: red;
}
form {
padding: 1em;
font: 80%/1 sans-serif;
width: 375px;
border: 1px solid #D5D5D5;
}
label {
float: left;
width: 15%;
margin-left: 20px;
margin-right: 0.5em;
padding-top: 0.2em;
text-align: right;
font-weight: bold;
color:#363636;
}
input {
margin-bottom: 8px;
}
.register {
float: left;
margin-left: 85px;
}
/* ----- table style ------- */
/* = Simple Table style (black header, grey/white stripes */
.simpletablestyle {
background-color:#E6E7E8;
clear:both;
width: 550px;
}
.simpletablestyle img {
border:0px;
}
.simpletablestyle td {
height:2em;
padding-left: 6px;
font-size:11px;
padding:5px 5px;
}
.simpletablestyle th {
background: url(#{request.contextPath}/resources/gfx/bkg-blkheader.png) black repeat-x top left;
font-size:12px;
font-weight:normal;
padding:0 10px 0 5px;
border-bottom:#999999 dotted 1px;
}
.simpletablestyle thead {
background: url(#{request.contextPath}/resources/gfx/bkg-blkheader.png) black repeat-x top left;
height:31px;
font-size:10px;
font-weight:bold;
color:#FFFFFF;
text-align:left;
}
.simpletablestyle .header a {
color:#94aebd;
}
.simpletablestype tfoot {
height: 20px;
font-size: 10px;
font-weight: bold;
background-color: #EAECEE;
text-align: center;
}
.simpletablestyle tr.header td {
padding: 0px 10px 0px 5px;
}
.simpletablestyle .subheader {
background-color: #e6e7e8;
font-size:10px;
font-weight:bold;
color:#000000;
text-align:left;
}
/* Using new CSS3 selectors for styling*/
.simpletablestyle tr:nth-child(odd) {
background: #f4f3f3;
}
.simpletablestyle tr:nth-child(even) {
background: #ffffff;
}
.simpletablestyle td a:hover {
color:#3883ce;
text-decoration:none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,84 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package baeldung.test;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.util.logging.Logger;
import javax.inject.Inject;
import baeldung.data.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import baeldung.model.Member;
import baeldung.service.MemberRegistration;
import baeldung.util.Resources;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(Arquillian.class)
public class MemberRegistrationTest {
@Deployment
public static Archive<?> createTestArchive() {
File[] files = Maven.resolver().loadPomFromFile("pom.xml")
.importRuntimeDependencies().resolve().withTransitivity().asFile();
return ShrinkWrap.create(WebArchive.class, "test.war")
.addClasses(
EntityManagerProducer.class,
Member.class,
MemberRegistration.class,
MemberRepository.class,
Resources.class,
QueryDslRepositoryExtension.class,
QueryDslSupport.class,
SecondaryPersistenceUnit.class,
SecondaryEntityManagerProducer.class,
SecondaryEntityManagerResolver.class)
.addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
.addAsResource("META-INF/apache-deltaspike.properties")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource("test-ds.xml")
.addAsWebInfResource("test-secondary-ds.xml")
.addAsLibraries(files);
}
@Inject
MemberRegistration memberRegistration;
@Inject
Logger log;
@Test
public void testRegister() throws Exception {
Member newMember = new Member();
newMember.setName("Jane Doe");
newMember.setEmail("jane@mailinator.com");
newMember.setPhoneNumber("2125551234");
memberRegistration.register(newMember);
assertNotNull(newMember.getId());
log.info(newMember.getName() + " was persisted with id " + newMember.getId());
}
}

View File

@ -0,0 +1 @@
globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="primary">
<jta-data-source>java:jboss/datasources/baeldung-jee7-seedTestDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
<persistence-unit name="secondary">
<jta-data-source>java:jboss/datasources/baeldung-jee7-seedTestSecondaryDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<!-- Uncomment to have test archives exported to the file system for inspection -->
<!-- <engine> -->
<!-- <property name="deploymentExportPath">target/</property> -->
<!-- </engine> -->
<!-- Force the use of the Servlet 3.0 protocol with all containers, as it is the most mature -->
<defaultProtocol type="Servlet 3.0" />
<!-- Example configuration for a remote WildFly instance -->
<container qualifier="jboss" default="true">
<!-- By default, arquillian will use the JBOSS_HOME environment variable. Alternatively, the configuration below can be uncommented. -->
<configuration>
<property name="jbossHome">target\wildfly-run\wildfly-10.0.0.Final</property>
</configuration>
</container>
</arquillian>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<datasources xmlns="http://www.jboss.org/ironjacamar/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd">
<datasource jndi-name="java:jboss/datasources/baeldung-jee7-seedTestDS"
pool-name="baeldung-jee7-seed-test" enabled="true"
use-java-context="true">
<connection-url>jdbc:h2:mem:baeldung-jee7-seed-test;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
</datasources>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<datasources xmlns="http://www.jboss.org/ironjacamar/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd">
<datasource jndi-name="java:jboss/datasources/baeldung-jee7-seedTestSecondaryDS"
pool-name="baeldung-jee7-seed-test" enabled="true"
use-java-context="true">
<connection-url>jdbc:h2:mem:baeldung-jee7-seed-test;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
</datasources>

View File

@ -0,0 +1,49 @@
package org.baeldung.gson.entities;
import java.util.Date;
import java.util.List;
public class ActorGson {
private String imdbId;
private Date dateOfBirth;
private List<String> filmography;
public ActorGson(String imdbId, Date dateOfBirth, List<String> filmography) {
super();
this.imdbId = imdbId;
this.dateOfBirth = dateOfBirth;
this.filmography = filmography;
}
@Override
public String toString() {
return "ActorGson [imdbId=" + imdbId + ", dateOfBirth=" + dateOfBirth + ", filmography=" + filmography + "]";
}
public String getImdbId() {
return imdbId;
}
public void setImdbId(String imdbId) {
this.imdbId = imdbId;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public List<String> getFilmography() {
return filmography;
}
public void setFilmography(List<String> filmography) {
this.filmography = filmography;
}
}

View File

@ -0,0 +1,48 @@
package org.baeldung.gson.entities;
import java.util.List;
public class Movie {
private String imdbId;
private String director;
private List<ActorGson> actors;
public Movie(String imdbID, String director, List<ActorGson> actors) {
super();
this.imdbId = imdbID;
this.director = director;
this.actors = actors;
}
@Override
public String toString() {
return "Movie [imdbId=" + imdbId + ", director=" + director + ", actors=" + actors + "]";
}
public String getImdbID() {
return imdbId;
}
public void setImdbID(String imdbID) {
this.imdbId = imdbID;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public List<ActorGson> getActors() {
return actors;
}
public void setActors(List<ActorGson> actors) {
this.actors = actors;
}
}

View File

@ -0,0 +1,46 @@
package org.baeldung.gson.entities;
import com.google.gson.annotations.Expose;
import java.util.List;
public class MovieWithNullValue {
@Expose
private String imdbId;
private String director;
@Expose
private List<ActorGson> actors;
public MovieWithNullValue(String imdbID, String director, List<ActorGson> actors) {
super();
this.imdbId = imdbID;
this.director = director;
this.actors = actors;
}
public String getImdbID() {
return imdbId;
}
public void setImdbID(String imdbID) {
this.imdbId = imdbID;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public List<ActorGson> getActors() {
return actors;
}
public void setActors(List<ActorGson> actors) {
this.actors = actors;
}
}

View File

@ -0,0 +1,40 @@
package org.baeldung.gson.serialization;
import com.google.gson.*;
import org.baeldung.gson.entities.ActorGson;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
public class ActorGsonDeserializer implements JsonDeserializer<ActorGson> {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
@Override
public ActorGson deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
JsonElement jsonImdbId = jsonObject.get("imdbId");
JsonElement jsonDateOfBirth = jsonObject.get("dateOfBirth");
JsonArray jsonFilmography = jsonObject.getAsJsonArray("filmography");
ArrayList<String> filmList = new ArrayList<String>();
if (jsonFilmography != null) {
for (int i = 0; i < jsonFilmography.size(); i++) {
filmList.add(jsonFilmography.get(i).getAsString());
}
}
ActorGson actorGson = null;
try {
actorGson = new ActorGson(jsonImdbId.getAsString(), sdf.parse(jsonDateOfBirth.getAsString()), filmList);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return actorGson;
}
}

View File

@ -0,0 +1,33 @@
package org.baeldung.gson.serialization;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.baeldung.gson.entities.ActorGson;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.stream.Collectors;
public class ActorGsonSerializer implements JsonSerializer<ActorGson> {
private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
@Override
public JsonElement serialize(ActorGson actor, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject actorJsonObj = new JsonObject();
actorJsonObj.addProperty("<strong>IMDB Code</strong>", actor.getImdbId());
actorJsonObj.addProperty("<strong>Date Of Birth</strong>", actor.getDateOfBirth() != null ? sdf.format(actor.getDateOfBirth()) : null);
actorJsonObj.addProperty("<strong>N° Film:</strong> ", actor.getFilmography() != null ? actor.getFilmography().size() : null);
actorJsonObj.addProperty("filmography", actor.getFilmography() != null ? convertFilmography(actor.getFilmography()) : null);
return actorJsonObj;
}
private String convertFilmography(List<String> filmography) {
return filmography.stream().collect(Collectors.joining("-"));
}
}

View File

@ -0,0 +1,38 @@
package org.baeldung.gson.deserialization;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.baeldung.gson.entities.ActorGson;
import org.baeldung.gson.entities.Movie;
import org.baeldung.gson.serialization.ActorGsonDeserializer;
import org.junit.Assert;
import org.junit.Test;
import java.text.ParseException;
public class GsonDeserializeTest {
@Test
public void whenSimpleDeserialize_thenCorrect() throws ParseException {
String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":" + "[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":" + "[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}";
Movie outputMovie = new Gson().fromJson(jsonInput, Movie.class);
String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorGson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 04:00:00 PDT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]";
Assert.assertEquals(outputMovie.toString(), expectedOutput);
}
@Test
public void whenCustomDeserialize_thenCorrect() throws ParseException {
String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":" + "[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":" + "[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}";
Gson gson = new GsonBuilder().registerTypeAdapter(ActorGson.class, new ActorGsonDeserializer()).create();
Movie outputMovie = gson.fromJson(jsonInput, Movie.class);
String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorGson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 12:00:00 PDT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]";
Assert.assertEquals(outputMovie.toString(), expectedOutput);
}
}

View File

@ -0,0 +1,48 @@
package org.baeldung.gson.serialization;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;
import org.baeldung.gson.entities.ActorGson;
import org.baeldung.gson.entities.Movie;
import org.baeldung.gson.entities.MovieWithNullValue;
import org.junit.Assert;
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
public class GsonSerializeTest {
@Test
public void whenSimpleSerialize_thenCorrect() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
ActorGson rudyYoungblood = new ActorGson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers"));
Movie movie = new Movie("tt0472043", "Mel Gibson", Arrays.asList(rudyYoungblood));
String expectedOutput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"Sep 21, 1982 12:00:00 AM\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}";
Assert.assertEquals(new Gson().toJson(movie), expectedOutput);
}
@Test
public void whenCustomSerialize_thenCorrect() throws ParseException {
Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().serializeNulls().disableHtmlEscaping().registerTypeAdapter(ActorGson.class, new ActorGsonSerializer()).create();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
ActorGson rudyYoungblood = new ActorGson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers"));
MovieWithNullValue movieWithNullValue = new MovieWithNullValue(null, "Mel Gibson", Arrays.asList(rudyYoungblood));
String expectedOutput = new GsonBuilder()
.setPrettyPrinting()
.serializeNulls()
.disableHtmlEscaping()
.create()
.toJson(new JsonParser()
.parse("{\"imdbId\":null,\"actors\":[{\"<strong>IMDB Code</strong>\":\"nm2199632\",\"<strong>Date Of Birth</strong>\":\"21-09-1982\",\"<strong>N° Film:</strong> \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}"));
Assert.assertEquals(gson.toJson(movieWithNullValue), expectedOutput);
}
}

12
hystrix/.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
*.class
#folders#
/target
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear
*.iml

View File

@ -6,16 +6,22 @@
<groupId>com.baeldung</groupId>
<artifactId>hystrix</artifactId>
<version>1.0</version>
<name>hystrix</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<properties>
<!-- General -->
<java.version>1.8</java.version>
<!-- Hystrix -->
<hystrix-core.version>1.4.10</hystrix-core.version>
<hystrix-core.version>1.5.4</hystrix-core.version>
<rxjava-core.version>0.20.7</rxjava-core.version>
<!-- Testing -->
@ -27,41 +33,76 @@
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<maven-surefire-plugin.version>2.19.1</maven-surefire-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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix-core.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix-metrics-event-stream.version}</version>
</dependency>
<!--<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-dashboard</artifactId>
<version>${hystrix-dashboard.version}</version>
</dependency>-->
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
<version>${rxjava-core.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest-all.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>

View File

@ -0,0 +1,20 @@
package com.baeldung.hystrix;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class AppConfig {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
@Bean
public ServletRegistrationBean adminServletRegistrationBean() {
return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream");
}
}

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