diff --git a/.gitignore b/.gitignore
index 210807d09e..e841cc4bf5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,8 +7,11 @@
# Eclipse
.settings/
+*.project
+*.classpath
.prefs
*.prefs
+.metadata/
# Intellij
.idea/
@@ -23,3 +26,4 @@ log/
target/
spring-openid/src/main/resources/application.properties
+.recommenders/
diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml
index 0e589ebf47..f99d85f564 100644
--- a/core-java-8/pom.xml
+++ b/core-java-8/pom.xml
@@ -41,6 +41,12 @@
3.3.2
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java b/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java
new file mode 100644
index 0000000000..125b6fbe38
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java
@@ -0,0 +1,16 @@
+package com.baeldung.datetime;
+
+import java.time.Duration;
+import java.time.LocalTime;
+import java.time.Period;
+
+public class UseDuration {
+
+ public LocalTime modifyDates(LocalTime localTime,Duration duration){
+ return localTime.plus(duration);
+ }
+
+ public Duration getDifferenceBetweenDates(LocalTime localTime1,LocalTime localTime2){
+ return Duration.between(localTime1, localTime2);
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java b/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java
new file mode 100644
index 0000000000..47b1b3f67d
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java
@@ -0,0 +1,46 @@
+package com.baeldung.datetime;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAdjusters;
+
+public class UseLocalDate {
+
+ public LocalDate getLocalDateUsingFactoryOfMethod(int year, int month, int dayOfMonth){
+ return LocalDate.of(year, month, dayOfMonth);
+ }
+
+ public LocalDate getLocalDateUsingParseMethod(String representation){
+ return LocalDate.parse(representation);
+ }
+
+ public LocalDate getLocalDateFromClock(){
+ LocalDate localDate = LocalDate.now();
+ return localDate;
+ }
+
+ public LocalDate getNextDay(LocalDate localDate){
+ return localDate.plusDays(1);
+ }
+
+ public LocalDate getPreviousDay(LocalDate localDate){
+ return localDate.minus(1, ChronoUnit.DAYS);
+ }
+
+ public DayOfWeek getDayOfWeek(LocalDate localDate){
+ DayOfWeek day = localDate.getDayOfWeek();
+ return day;
+ }
+
+ public LocalDate getFirstDayOfMonth(){
+ LocalDate firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
+ return firstDayOfMonth;
+ }
+
+ public LocalDateTime getStartOfDay(LocalDate localDate){
+ LocalDateTime startofDay = localDate.atStartOfDay();
+ return startofDay;
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java b/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java
new file mode 100644
index 0000000000..7aa1eaa276
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java
@@ -0,0 +1,11 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDateTime;
+
+public class UseLocalDateTime {
+
+ public LocalDateTime getLocalDateTimeUsingParseMethod(String representation){
+ return LocalDateTime.parse(representation);
+ }
+
+}
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java b/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java
new file mode 100644
index 0000000000..e13fd10d6f
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java
@@ -0,0 +1,35 @@
+package com.baeldung.datetime;
+
+import java.time.LocalTime;
+import java.time.temporal.ChronoUnit;
+
+public class UseLocalTime {
+
+ public LocalTime getLocalTimeUsingFactoryOfMethod(int hour, int min, int seconds){
+ LocalTime localTime = LocalTime.of(hour, min, seconds);
+ return localTime;
+ }
+
+ public LocalTime getLocalTimeUsingParseMethod(String timeRepresentation){
+ LocalTime localTime = LocalTime.parse(timeRepresentation);
+ return localTime;
+ }
+
+ public LocalTime getLocalTimeFromClock(){
+ LocalTime localTime = LocalTime.now();
+ return localTime;
+ }
+
+ public LocalTime addAnHour(LocalTime localTime){
+ LocalTime newTime = localTime.plus(1,ChronoUnit.HOURS);
+ return newTime;
+ }
+
+ public int getHourFromLocalTime(LocalTime localTime){
+ return localTime.getHour();
+ }
+
+ public LocalTime getLocalTimeWithMinuteSetToValue(LocalTime localTime, int minute){
+ return localTime.withMinute(minute);
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java b/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java
new file mode 100644
index 0000000000..326cfad650
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java
@@ -0,0 +1,15 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDate;
+import java.time.Period;
+
+public class UsePeriod {
+
+ public LocalDate modifyDates(LocalDate localDate,Period period){
+ return localDate.plus(period);
+ }
+
+ public Period getDifferenceBetweenDates(LocalDate localDate1,LocalDate localDate2){
+ return Period.between(localDate1, localDate2);
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java b/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java
new file mode 100644
index 0000000000..1ddb096cf6
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java
@@ -0,0 +1,19 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Calendar;
+import java.util.Date;
+
+public class UseToInstant {
+
+ public LocalDateTime convertDateToLocalDate(Date date){
+ LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
+ return localDateTime;
+ }
+
+ public LocalDateTime convertDateToLocalDate(Calendar calendar){
+ LocalDateTime localDateTime = LocalDateTime.ofInstant(calendar.toInstant(), ZoneId.systemDefault());
+ return localDateTime;
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java b/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java
new file mode 100644
index 0000000000..0369de9835
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java
@@ -0,0 +1,13 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+public class UseZonedDateTime {
+
+ public ZonedDateTime getZonedDateTime(LocalDateTime localDateTime,ZoneId zoneId){
+ ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
+ return zonedDateTime;
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/enums/Pizza.java b/core-java-8/src/main/java/com/baeldung/enums/Pizza.java
new file mode 100644
index 0000000000..5bc2d9a9eb
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/enums/Pizza.java
@@ -0,0 +1,91 @@
+package com.baeldung.enums;
+
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Pizza {
+
+ private static EnumSet deliveredPizzaStatuses =
+ EnumSet.of(PizzaStatusEnum.DELIVERED);
+
+ private PizzaStatusEnum status;
+
+ public enum PizzaStatusEnum {
+ ORDERED(5) {
+ @Override
+ public boolean isOrdered() {
+ return true;
+ }
+ },
+ READY(2) {
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+ },
+ DELIVERED(0) {
+ @Override
+ public boolean isDelivered() {
+ return true;
+ }
+ };
+
+ private int timeToDelivery;
+
+ public boolean isOrdered() {
+ return false;
+ }
+
+ public boolean isReady() {
+ return false;
+ }
+
+ public boolean isDelivered() {
+ return false;
+ }
+
+ public int getTimeToDelivery() {
+ return timeToDelivery;
+ }
+
+ PizzaStatusEnum(int timeToDelivery) {
+ this.timeToDelivery = timeToDelivery;
+ }
+ }
+
+ public PizzaStatusEnum getStatus() {
+ return status;
+ }
+
+ public void setStatus(PizzaStatusEnum status) {
+ this.status = status;
+ }
+
+ public boolean isDeliverable() {
+ return this.status.isReady();
+ }
+
+ public void printTimeToDeliver() {
+ System.out.println("Time to delivery is " + this.getStatus().getTimeToDelivery() + " days");
+ }
+
+ public static List getAllUndeliveredPizzas(List input) {
+ return input.stream().filter((s) -> !deliveredPizzaStatuses.contains(s.getStatus())).collect(Collectors.toList());
+ }
+
+ public static EnumMap> groupPizzaByStatus(List pzList) {
+ return pzList.stream().collect(
+ Collectors.groupingBy(Pizza::getStatus,
+ () -> new EnumMap<>(PizzaStatusEnum.class), Collectors.toList()));
+ }
+
+ public void deliver() {
+ if (isDeliverable()) {
+ PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy().deliver(this);
+ this.setStatus(PizzaStatusEnum.DELIVERED);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java
new file mode 100644
index 0000000000..ed65919387
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java
@@ -0,0 +1,18 @@
+package com.baeldung.enums;
+
+public enum PizzaDeliveryStrategy {
+ EXPRESS {
+ @Override
+ public void deliver(Pizza pz) {
+ System.out.println("Pizza will be delivered in express mode");
+ }
+ },
+ NORMAL {
+ @Override
+ public void deliver(Pizza pz) {
+ System.out.println("Pizza will be delivered in normal mode");
+ }
+ };
+
+ public abstract void deliver(Pizza pz);
+}
diff --git a/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java
new file mode 100644
index 0000000000..5ccff5e959
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java
@@ -0,0 +1,22 @@
+package com.baeldung.enums;
+
+
+public enum PizzaDeliverySystemConfiguration {
+ INSTANCE;
+
+ PizzaDeliverySystemConfiguration() {
+ // Do the configuration initialization which
+ // involves overriding defaults like delivery strategy
+ }
+
+ private PizzaDeliveryStrategy deliveryStrategy = PizzaDeliveryStrategy.NORMAL;
+
+ public static PizzaDeliverySystemConfiguration getInstance() {
+ return INSTANCE;
+ }
+
+ public PizzaDeliveryStrategy getDeliveryStrategy() {
+ return deliveryStrategy;
+ }
+
+}
diff --git a/core-java-8/src/main/java/com/baeldung/streamApi/Product.java b/core-java-8/src/main/java/com/baeldung/streamApi/Product.java
new file mode 100644
index 0000000000..18f3a61904
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/streamApi/Product.java
@@ -0,0 +1,51 @@
+package com.baeldung.streamApi;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+/**
+ * Created by Alex Vengr
+ */
+public class Product {
+
+ private int price;
+
+ private String name;
+
+ private boolean utilize;
+
+ public Product(int price, String name) {
+ this(price);
+ this.name = name;
+ }
+
+ public Product(int price) {
+ this.price = price;
+ }
+
+ public Product() {
+ }
+
+ public int getPrice() {
+ return price;
+ }
+
+ public void setPrice(int price) {
+ this.price = price;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public static Stream streamOf(List list) {
+ return (list == null || list.isEmpty()) ? Stream.empty() : list.stream();
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTest.java
new file mode 100644
index 0000000000..8af33393be
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTest.java
@@ -0,0 +1,55 @@
+package com.baeldung.datetime;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.Month;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UseLocalDateTest {
+
+ UseLocalDate useLocalDate = new UseLocalDate();
+
+ @Test
+ public void givenValues_whenUsingFactoryOf_thenLocalDate(){
+ Assert.assertEquals("2016-05-10",useLocalDate.getLocalDateUsingFactoryOfMethod(2016,5,10).toString());
+ }
+
+ @Test
+ public void givenString_whenUsingParse_thenLocalDate(){
+ Assert.assertEquals("2016-05-10",useLocalDate.getLocalDateUsingParseMethod("2016-05-10").toString());
+ }
+
+ @Test
+ public void whenUsingClock_thenLocalDate(){
+ Assert.assertEquals(LocalDate.now(),useLocalDate.getLocalDateFromClock());
+ }
+
+ @Test
+ public void givenDate_whenUsingPlus_thenNextDay(){
+ Assert.assertEquals(LocalDate.now().plusDays(1),useLocalDate.getNextDay(LocalDate.now()));
+ }
+
+ @Test
+ public void givenDate_whenUsingMinus_thenPreviousDay(){
+ Assert.assertEquals(LocalDate.now().minusDays(1),useLocalDate.getPreviousDay(LocalDate.now()));
+ }
+
+ @Test
+ public void givenToday_whenUsingGetDayOfWeek_thenDayOfWeek(){
+ Assert.assertEquals(DayOfWeek.SUNDAY,useLocalDate.getDayOfWeek(LocalDate.parse("2016-05-22")));
+ }
+
+ @Test
+ public void givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth(){
+ Assert.assertEquals(1,useLocalDate.getFirstDayOfMonth().getDayOfMonth());
+ }
+
+ @Test
+ public void givenLocalDate_whenUsingAtStartOfDay_thenReturnMidnight(){
+ Assert.assertEquals(LocalDateTime.parse("2016-05-22T00:00:00"),useLocalDate.getStartOfDay(LocalDate.parse("2016-05-22")));
+ }
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeTest.java
new file mode 100644
index 0000000000..69a289fd02
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.Month;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UseLocalDateTimeTest {
+
+ UseLocalDateTime useLocalDateTime = new UseLocalDateTime();
+
+ @Test
+ public void givenString_whenUsingParse_thenLocalDateTime(){
+ Assert.assertEquals(LocalDate.of(2016, Month.MAY, 10),useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalDate());
+ Assert.assertEquals(LocalTime.of(6,30),useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalTime());
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeTest.java
new file mode 100644
index 0000000000..7776fad363
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.datetime;
+
+import java.time.LocalTime;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UseLocalTimeTest {
+
+ UseLocalTime useLocalTime = new UseLocalTime();
+
+ @Test
+ public void givenValues_whenUsingFactoryOf_thenLocalTime(){
+ Assert.assertEquals("07:07:07",useLocalTime.getLocalTimeUsingFactoryOfMethod(7,7,7).toString());
+ }
+
+ @Test
+ public void givenString_whenUsingParse_thenLocalTime(){
+ Assert.assertEquals("06:30",useLocalTime.getLocalTimeUsingParseMethod("06:30").toString());
+ }
+
+ @Test
+ public void givenTime_whenAddHour_thenLocalTime(){
+ Assert.assertEquals("07:30",useLocalTime.addAnHour(LocalTime.of(6,30)).toString());
+ }
+
+ @Test
+ public void getHourFromLocalTime(){
+ Assert.assertEquals(1, useLocalTime.getHourFromLocalTime(LocalTime.of(1,1)));
+ }
+
+ @Test
+ public void getLocalTimeWithMinuteSetToValue(){
+ Assert.assertEquals(LocalTime.of(10, 20), useLocalTime.getLocalTimeWithMinuteSetToValue(LocalTime.of(10,10), 20));
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodTest.java
new file mode 100644
index 0000000000..8a3228aaa5
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodTest.java
@@ -0,0 +1,29 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UsePeriodTest {
+ UsePeriod usingPeriod=new UsePeriod();
+
+ @Test
+ public void givenPeriodAndLocalDate_thenCalculateModifiedDate(){
+ Period period = Period.ofDays(1);
+ LocalDate localDate = LocalDate.parse("2007-05-10");
+ Assert.assertEquals(localDate.plusDays(1),usingPeriod.modifyDates(localDate, period));
+ }
+
+ @Test
+ public void givenDates_thenGetPeriod(){
+ LocalDate localDate1 = LocalDate.parse("2007-05-10");
+ LocalDate localDate2 = LocalDate.parse("2007-05-15");
+
+ Assert.assertEquals(Period.ofDays(5), usingPeriod.getDifferenceBetweenDates(localDate1, localDate2));
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeTest.java
new file mode 100644
index 0000000000..5af01ad678
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.datetime;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UseZonedDateTimeTest {
+
+ UseZonedDateTime zonedDateTime=new UseZonedDateTime();
+
+ @Test
+ public void givenZoneId_thenZonedDateTime(){
+ ZoneId zoneId=ZoneId.of("Europe/Paris");
+ ZonedDateTime zonedDatetime=zonedDateTime.getZonedDateTime(LocalDateTime.parse("2016-05-20T06:30"), zoneId);
+ Assert.assertEquals(zoneId,ZoneId.from(zonedDatetime));
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java b/core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java
new file mode 100644
index 0000000000..deeebaa240
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java
@@ -0,0 +1,80 @@
+package com.baeldung.enums;
+
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+
+import static junit.framework.TestCase.assertTrue;
+
+public class PizzaTest {
+
+ @Test
+ public void givenPizaOrder_whenReady_thenDeliverable() {
+ Pizza testPz = new Pizza();
+ testPz.setStatus(Pizza.PizzaStatusEnum.READY);
+ assertTrue(testPz.isDeliverable());
+ }
+
+ @Test
+ public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved() {
+ List pzList = new ArrayList<>();
+ Pizza pz1 = new Pizza();
+ pz1.setStatus(Pizza.PizzaStatusEnum.DELIVERED);
+
+ Pizza pz2 = new Pizza();
+ pz2.setStatus(Pizza.PizzaStatusEnum.ORDERED);
+
+ Pizza pz3 = new Pizza();
+ pz3.setStatus(Pizza.PizzaStatusEnum.ORDERED);
+
+ Pizza pz4 = new Pizza();
+ pz4.setStatus(Pizza.PizzaStatusEnum.READY);
+
+ pzList.add(pz1);
+ pzList.add(pz2);
+ pzList.add(pz3);
+ pzList.add(pz4);
+
+ List undeliveredPzs = Pizza.getAllUndeliveredPizzas(pzList);
+ assertTrue(undeliveredPzs.size() == 3);
+ }
+
+ @Test
+ public void givenPizaOrders_whenGroupByStatusCalled_thenCorrectlyGrouped() {
+
+ List pzList = new ArrayList<>();
+ Pizza pz1 = new Pizza();
+ pz1.setStatus(Pizza.PizzaStatusEnum.DELIVERED);
+
+ Pizza pz2 = new Pizza();
+ pz2.setStatus(Pizza.PizzaStatusEnum.ORDERED);
+
+ Pizza pz3 = new Pizza();
+ pz3.setStatus(Pizza.PizzaStatusEnum.ORDERED);
+
+ Pizza pz4 = new Pizza();
+ pz4.setStatus(Pizza.PizzaStatusEnum.READY);
+
+ pzList.add(pz1);
+ pzList.add(pz2);
+ pzList.add(pz3);
+ pzList.add(pz4);
+
+ EnumMap> map = Pizza.groupPizzaByStatus(pzList);
+ assertTrue(map.get(Pizza.PizzaStatusEnum.DELIVERED).size() == 1);
+ assertTrue(map.get(Pizza.PizzaStatusEnum.ORDERED).size() == 2);
+ assertTrue(map.get(Pizza.PizzaStatusEnum.READY).size() == 1);
+ }
+
+ @Test
+ public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() {
+ Pizza pz = new Pizza();
+ pz.setStatus(Pizza.PizzaStatusEnum.READY);
+ pz.deliver();
+ assertTrue(pz.getStatus() == Pizza.PizzaStatusEnum.DELIVERED);
+ }
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiTest.java
new file mode 100644
index 0000000000..37326c6d26
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiTest.java
@@ -0,0 +1,263 @@
+package com.baeldung.java8;
+
+import com.baeldung.streamApi.Product;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.*;
+
+import static org.junit.Assert.*;
+
+public class Java8StreamApiTest {
+
+ private long counter;
+
+ private static Logger log = LoggerFactory.getLogger(Java8StreamApiTest.class);
+
+ private List productList;
+
+ @Before
+ public void init() {
+ productList = Arrays.asList(
+ new Product(23, "potatoes"), new Product(14, "orange"),
+ new Product(13, "lemon"), new Product(23, "bread"),
+ new Product(13, "sugar"));
+ }
+
+ @Test
+ public void checkPipeline_whenStreamOneElementShorter_thenCorrect() {
+
+ List list = Arrays.asList("abc1", "abc2", "abc3");
+ long size = list.stream().skip(1)
+ .map(element -> element.substring(0, 3)).count();
+ assertEquals(list.size() - 1, size);
+ }
+
+ @Test
+ public void checkOrder_whenChangeQuantityOfMethodCalls_thenCorrect() {
+
+ List list = Arrays.asList("abc1", "abc2", "abc3");
+
+ counter = 0;
+ long sizeFirst = list.stream()
+ .skip(2).map(element -> {
+ wasCalled();
+ return element.substring(0, 3);
+ }).count();
+ assertEquals(1, counter);
+
+ counter = 0;
+ long sizeSecond = list.stream().map(element -> {
+ wasCalled();
+ return element.substring(0, 3);
+ }).skip(2).count();
+ assertEquals(3, counter);
+ }
+
+ @Test
+ public void createEmptyStream_whenEmpty_thenCorrect() {
+
+ Stream streamEmpty = Stream.empty();
+ assertEquals(0, streamEmpty.count());
+
+ List names = Collections.emptyList();
+ Stream streamOf = Product.streamOf(names);
+ assertTrue(streamOf.count() == 0);
+ }
+
+ @Test
+ public void createStream_whenCreated_thenCorrect() {
+
+ Collection collection = Arrays.asList("a", "b", "c");
+ Stream streamOfCollection = collection.stream();
+ assertEquals(3, streamOfCollection.count());
+
+ Stream streamOfArray = Stream.of("a", "b", "c");
+ assertEquals(3, streamOfArray.count());
+
+ String[] arr = new String[]{"a", "b", "c"};
+ Stream streamOfArrayPart = Arrays.stream(arr, 1, 3);
+ assertEquals(2, streamOfArrayPart.count());
+
+ IntStream intStream = IntStream.range(1, 3);
+ LongStream longStream = LongStream.rangeClosed(1, 3);
+ Random random = new Random();
+ DoubleStream doubleStream = random.doubles(3);
+ assertEquals(2, intStream.count());
+ assertEquals(3, longStream.count());
+ assertEquals(3, doubleStream.count());
+
+ IntStream streamOfChars = "abc".chars();
+ IntStream str = "".chars();
+ assertEquals(3, streamOfChars.count());
+
+ Stream streamOfString = Pattern.compile(", ").splitAsStream("a, b, c");
+ assertEquals("a", streamOfString.findFirst().get());
+
+ Path path = getPath();
+ Stream streamOfStrings = null;
+ try {
+ streamOfStrings = Files.lines(path, Charset.forName("UTF-8"));
+ } catch (IOException e) {
+ log.error("Error creating streams from paths {}", path, e.getMessage(), e);
+ }
+ assertEquals("a", streamOfStrings.findFirst().get());
+
+ Stream streamBuilder = Stream.builder().add("a").add("b").add("c").build();
+ assertEquals(3, streamBuilder.count());
+
+ Stream streamGenerated = Stream.generate(() -> "element").limit(10);
+ assertEquals(10, streamGenerated.count());
+
+ Stream streamIterated = Stream.iterate(40, n -> n + 2).limit(20);
+ assertTrue(40 <= streamIterated.findAny().get());
+ }
+
+ @Test
+ public void runStreamPipeline_whenOrderIsRight_thenCorrect() {
+
+ List list = Arrays.asList("abc1", "abc2", "abc3");
+ Optional stream = list.stream()
+ .filter(element -> {
+ log.info("filter() was called");
+ return element.contains("2");
+ }).map(element -> {
+ log.info("map() was called");
+ return element.toUpperCase();
+ }).findFirst();
+ }
+
+ @Test
+ public void reduce_whenExpected_thenCorrect() {
+
+ OptionalInt reduced = IntStream.range(1, 4).reduce((a, b) -> a + b);
+ assertEquals(6, reduced.getAsInt());
+
+ int reducedTwoParams = IntStream.range(1, 4).reduce(10, (a, b) -> a + b);
+ assertEquals(16, reducedTwoParams);
+
+ int reducedThreeParams = Stream.of(1, 2, 3)
+ .reduce(10, (a, b) -> a + b, (a, b) -> {
+ log.info("combiner was called");
+ return a + b;
+ });
+ assertEquals(16, reducedThreeParams);
+
+ int reducedThreeParamsParallel = Arrays.asList(1, 2, 3).parallelStream()
+ .reduce(10, (a, b) -> a + b, (a, b) -> {
+ log.info("combiner was called");
+ return a + b;
+ });
+ assertEquals(36, reducedThreeParamsParallel);
+ }
+
+ @Test
+ public void collecting_whenAsExpected_thenCorrect() {
+
+ List collectorCollection = productList.stream()
+ .map(Product::getName).collect(Collectors.toList());
+
+ assertTrue(collectorCollection instanceof List);
+ assertEquals(5, collectorCollection.size());
+
+ String listToString = productList.stream().map(Product::getName)
+ .collect(Collectors.joining(", ", "[", "]"));
+
+ assertTrue(listToString.contains(",") && listToString.contains("[") && listToString.contains("]"));
+
+ double averagePrice = productList.stream().collect(Collectors.averagingInt(Product::getPrice));
+ assertTrue(17.2 == averagePrice);
+
+ int summingPrice = productList.stream().collect(Collectors.summingInt(Product::getPrice));
+ assertEquals(86, summingPrice);
+
+ IntSummaryStatistics statistics = productList.stream()
+ .collect(Collectors.summarizingInt(Product::getPrice));
+ assertEquals(23, statistics.getMax());
+
+ Map> collectorMapOfLists = productList.stream()
+ .collect(Collectors.groupingBy(Product::getPrice));
+ assertEquals(3, collectorMapOfLists.keySet().size());
+
+ Map> mapPartioned = productList.stream()
+ .collect(Collectors.partitioningBy(element -> element.getPrice() > 15));
+ assertEquals(2, mapPartioned.keySet().size());
+
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void collect_whenThrows_thenCorrect() {
+ Set unmodifiableSet = productList.stream()
+ .collect(Collectors.collectingAndThen(Collectors.toSet(),
+ Collections::unmodifiableSet));
+ unmodifiableSet.add(new Product(4, "tea"));
+ }
+
+ @Test
+ public void customCollector_whenResultContainsAllElementsFrSource_thenCorrect() {
+ Collector> toLinkedList =
+ Collector.of(LinkedList::new, LinkedList::add,
+ (first, second) -> {
+ first.addAll(second);
+ return first;
+ });
+
+ LinkedList linkedListOfPersons = productList.stream().collect(toLinkedList);
+ assertTrue(linkedListOfPersons.containsAll(productList));
+ }
+
+ @Test
+ public void parallelStream_whenWorks_thenCorrect() {
+ Stream streamOfCollection = productList.parallelStream();
+ boolean isParallel = streamOfCollection.isParallel();
+ boolean haveBigPrice = streamOfCollection.map(product -> product.getPrice() * 12)
+ .anyMatch(price -> price > 200);
+ assertTrue(isParallel && haveBigPrice);
+ }
+
+ @Test
+ public void parallel_whenIsParallel_thenCorrect() {
+ IntStream intStreamParallel =
+ IntStream.range(1, 150).parallel().map(element -> element * 34);
+ boolean isParallel = intStreamParallel.isParallel();
+ assertTrue(isParallel);
+ }
+
+ @Test
+ public void parallel_whenIsSequential_thenCorrect() {
+ IntStream intStreamParallel =
+ IntStream.range(1, 150).parallel().map(element -> element * 34);
+ IntStream intStreamSequential = intStreamParallel.sequential();
+ boolean isParallel = intStreamParallel.isParallel();
+ assertFalse(isParallel);
+ }
+
+ private Path getPath() {
+ Path path = null;
+ try {
+ path = Files.createTempFile(null, ".txt");
+ } catch (IOException e) {
+ log.error(e.getMessage());
+ }
+
+ try (BufferedWriter writer = Files.newBufferedWriter(path)) {
+ writer.write("a\nb\nc");
+ } catch (IOException e) {
+ log.error(e.getMessage());
+ }
+ return path;
+ }
+
+ private void wasCalled() {
+ counter++;
+ }
+}
diff --git a/core-java/pom.xml b/core-java/pom.xml
index e3a9043b09..cb194a6d9f 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -9,7 +9,11 @@
-
+
+ net.sourceforge.collections
+ collections-generic
+ 4.01
+
com.google.guava
guava
@@ -122,8 +126,8 @@
maven-compiler-plugin
${maven-compiler-plugin.version}
-
- 1.7
+
+ 1.8
diff --git a/core-java/src/main/java/com/baeldung/enums/Pizza.java b/core-java/src/main/java/com/baeldung/enums/Pizza.java
new file mode 100644
index 0000000000..7742781081
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/enums/Pizza.java
@@ -0,0 +1,110 @@
+package com.baeldung.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.collections15.Predicate;
+
+import java.io.IOException;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Pizza {
+
+ private static EnumSet undeliveredPizzaStatuses =
+ EnumSet.of(PizzaStatus.ORDERED, PizzaStatus.READY);
+
+ private PizzaStatus status;
+
+ @JsonFormat(shape = JsonFormat.Shape.OBJECT)
+ public enum PizzaStatus {
+ ORDERED(5) {
+ @Override
+ public boolean isOrdered() {
+ return true;
+ }
+ },
+ READY(2) {
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+ },
+ DELIVERED(0) {
+ @Override
+ public boolean isDelivered() {
+ return true;
+ }
+ };
+
+ private int timeToDelivery;
+
+ public boolean isOrdered() {
+ return false;
+ }
+
+ public boolean isReady() {
+ return false;
+ }
+
+ public boolean isDelivered() {
+ return false;
+ }
+
+ @JsonProperty("timeToDelivery")
+ public int getTimeToDelivery() {
+ return timeToDelivery;
+ }
+
+ PizzaStatus(int timeToDelivery) {
+ this.timeToDelivery = timeToDelivery;
+ }
+ }
+
+ public PizzaStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(PizzaStatus status) {
+ this.status = status;
+ }
+
+ public boolean isDeliverable() {
+ return this.status.isReady();
+ }
+
+ public void printTimeToDeliver() {
+ System.out.println("Time to delivery is " + this.getStatus().getTimeToDelivery() + " days");
+ }
+
+ public static List getAllUndeliveredPizzas(List input) {
+ return input.stream().filter(
+ (s) -> undeliveredPizzaStatuses.contains(s.getStatus()))
+ .collect(Collectors.toList());
+ }
+
+ public static EnumMap>
+ groupPizzaByStatus(List pzList) {
+ return pzList.stream().collect(
+ Collectors.groupingBy(Pizza::getStatus,
+ () -> new EnumMap<>(PizzaStatus.class), Collectors.toList()));
+ }
+
+ public void deliver() {
+ if (isDeliverable()) {
+ PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy().deliver(this);
+ this.setStatus(PizzaStatus.DELIVERED);
+ }
+ }
+
+ public static String getJsonString(Pizza pz) throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(pz);
+ }
+
+ private static Predicate thatAreNotDelivered() {
+ return entry -> undeliveredPizzaStatuses.contains(entry.getStatus());
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java b/core-java/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java
new file mode 100644
index 0000000000..ed65919387
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java
@@ -0,0 +1,18 @@
+package com.baeldung.enums;
+
+public enum PizzaDeliveryStrategy {
+ EXPRESS {
+ @Override
+ public void deliver(Pizza pz) {
+ System.out.println("Pizza will be delivered in express mode");
+ }
+ },
+ NORMAL {
+ @Override
+ public void deliver(Pizza pz) {
+ System.out.println("Pizza will be delivered in normal mode");
+ }
+ };
+
+ public abstract void deliver(Pizza pz);
+}
diff --git a/core-java/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java b/core-java/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java
new file mode 100644
index 0000000000..a276b3c000
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java
@@ -0,0 +1,21 @@
+package com.baeldung.enums;
+
+public enum PizzaDeliverySystemConfiguration {
+ INSTANCE;
+
+ PizzaDeliverySystemConfiguration() {
+ // Do the configuration initialization which
+ // involves overriding defaults like delivery strategy
+ }
+
+ private PizzaDeliveryStrategy deliveryStrategy = PizzaDeliveryStrategy.NORMAL;
+
+ public static PizzaDeliverySystemConfiguration getInstance() {
+ return INSTANCE;
+ }
+
+ public PizzaDeliveryStrategy getDeliveryStrategy() {
+ return deliveryStrategy;
+ }
+
+}
diff --git a/core-java/src/test/java/org/baeldung/java/enums/PizzaTest.java b/core-java/src/test/java/org/baeldung/java/enums/PizzaTest.java
new file mode 100644
index 0000000000..a6814ee600
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/enums/PizzaTest.java
@@ -0,0 +1,80 @@
+package org.baeldung.java.enums;
+
+
+import com.baeldung.enums.Pizza;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+
+import static junit.framework.TestCase.assertTrue;
+
+
+public class PizzaTest {
+ @Test
+ public void givenPizaOrder_whenReady_thenDeliverable() {
+ Pizza testPz = new Pizza();
+ testPz.setStatus(Pizza.PizzaStatus.READY);
+ assertTrue(testPz.isDeliverable());
+ }
+
+ @Test
+ public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved() {
+ List pzList = new ArrayList<>();
+ Pizza pz1 = new Pizza();
+ pz1.setStatus(Pizza.PizzaStatus.DELIVERED);
+
+ Pizza pz2 = new Pizza();
+ pz2.setStatus(Pizza.PizzaStatus.ORDERED);
+
+ Pizza pz3 = new Pizza();
+ pz3.setStatus(Pizza.PizzaStatus.ORDERED);
+
+ Pizza pz4 = new Pizza();
+ pz4.setStatus(Pizza.PizzaStatus.READY);
+
+ pzList.add(pz1);
+ pzList.add(pz2);
+ pzList.add(pz3);
+ pzList.add(pz4);
+
+ List undeliveredPzs = Pizza.getAllUndeliveredPizzas(pzList);
+ assertTrue(undeliveredPzs.size() == 3);
+ }
+
+ @Test
+ public void givenPizaOrders_whenGroupByStatusCalled_thenCorrectlyGrouped() {
+
+ List pzList = new ArrayList<>();
+ Pizza pz1 = new Pizza();
+ pz1.setStatus(Pizza.PizzaStatus.DELIVERED);
+
+ Pizza pz2 = new Pizza();
+ pz2.setStatus(Pizza.PizzaStatus.ORDERED);
+
+ Pizza pz3 = new Pizza();
+ pz3.setStatus(Pizza.PizzaStatus.ORDERED);
+
+ Pizza pz4 = new Pizza();
+ pz4.setStatus(Pizza.PizzaStatus.READY);
+
+ pzList.add(pz1);
+ pzList.add(pz2);
+ pzList.add(pz3);
+ pzList.add(pz4);
+
+ EnumMap> map = Pizza.groupPizzaByStatus(pzList);
+ assertTrue(map.get(Pizza.PizzaStatus.DELIVERED).size() == 1);
+ assertTrue(map.get(Pizza.PizzaStatus.ORDERED).size() == 2);
+ assertTrue(map.get(Pizza.PizzaStatus.READY).size() == 1);
+ }
+
+ @Test
+ public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() {
+ Pizza pz = new Pizza();
+ pz.setStatus(Pizza.PizzaStatus.READY);
+ pz.deliver();
+ assertTrue(pz.getStatus() == Pizza.PizzaStatus.DELIVERED);
+ }
+}
diff --git a/dependency-injection/.gitignore b/dependency-injection/.gitignore
new file mode 100644
index 0000000000..6531dfc93f
--- /dev/null
+++ b/dependency-injection/.gitignore
@@ -0,0 +1,12 @@
+RemoteSystemsTempFiles/
+.classpath
+.project
+.settings/
+bin/
+.metadata/
+docs/*.autosave
+docs/*.autosave
+.recommenders/
+build/
+.gradle/
+.DS_Store
diff --git a/dependency-injection/build.gradle b/dependency-injection/build.gradle
new file mode 100644
index 0000000000..968636154d
--- /dev/null
+++ b/dependency-injection/build.gradle
@@ -0,0 +1,43 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+allprojects {
+ apply plugin: 'java'
+ sourceCompatibility = 1.6
+ targetCompatibility = 1.6
+}
+
+repositories {
+ mavenCentral()
+}
+
+sourceSets {
+ main {
+ resources.srcDirs = ["src/main/java","src/main/resources"]
+ }
+ test {
+ resources.srcDirs = ["src/main/java", "src/main/resources", "src/test/resources"]
+ }
+}
+
+configurations {
+ compile
+}
+
+test {
+ testLogging {
+ events 'started', 'passed'
+ }
+}
+
+dependencies {
+ testCompile('junit:junit:4.11')
+ testCompile('org.mockito:mockito-all:1.10.19')
+ testCompile group: 'org.springframework', name: 'spring-test', version: '4.2.6.RELEASE'
+ testCompile group: 'org.springframework', name: 'spring-core', version: '4.2.6.RELEASE'
+ testCompile group: 'org.springframework', name: 'spring-beans', version: '4.2.6.RELEASE'
+ testCompile group: 'org.springframework', name: 'spring-context', version: '4.2.6.RELEASE'
+ testCompile group: 'javax.inject', name: 'javax.inject', version: '1'
+
+ testRuntime('junit:junit:4.11')
+}
diff --git a/dependency-injection/docs/autowired-name-demo-classdiagram.png b/dependency-injection/docs/autowired-name-demo-classdiagram.png
new file mode 100644
index 0000000000..f367fdbf41
Binary files /dev/null and b/dependency-injection/docs/autowired-name-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/autowired-type-demo-classdiagram.png b/dependency-injection/docs/autowired-type-demo-classdiagram.png
new file mode 100644
index 0000000000..5f3f341556
Binary files /dev/null and b/dependency-injection/docs/autowired-type-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/autowired-type-demo-classdiagram.xml b/dependency-injection/docs/autowired-type-demo-classdiagram.xml
new file mode 100644
index 0000000000..71dc839457
--- /dev/null
+++ b/dependency-injection/docs/autowired-type-demo-classdiagram.xml
@@ -0,0 +1 @@
+7Vjvb+I4EP1rkO4+7KkhhW0/8qt3J3V1Velq7z5VbmKIb50M55hS9q/fGXtMEgLXrprthwqEEH6ZOJ5573nAvXiSP/1uxCr7BKnUvf5Z+tSLp71+/6If4ycBWw8MBpceWBqVeiiqgLn6Jhk8Y3StUlk2Ai2AtmrVBBMoCpnYBiaMgU0zbAG6+dSVWIYnVsA8EbqNflGpzUJawwr/Q6plFp4cDTm/B5F8XRpYF/y8Xj9euJe/nIswFydaZiKFTQ2KZ1hWA4Az07f8aSI1lTaUzd93deTqbt1GFry2Z24I67DbkLtMsRQ8BGMzWEIh9KxCxy4/STOc4SizucavEX7Fh5rt34y7wT80+G3ghumImKFZV7K4y1Th0SuFK/K3/Cut3bIaxNoCQtUKrgFW/By/Zlro0bQZKmFtEo7CsROSMEvJUR93JUclS8glLhlDjNTCqsfm7II1tdzF8a2YlqC7QsAKVGHL2sw3BGAAuyO6HPgZ2Rz9yC0jcIRf/IxhVFtaBTkeD3PKeT4KveYMrpTU6QgLulFGplOZQ4v1cqNyLQqit0boAgobtEBjodUSaZsmWGdpEHiUxir0zYgvWOJonGRKp9diC2uqc2nRFGE0zsCobzitCM/Ay8Yy6WiwesSc7mRtGFlizE2gmO700LUoCaCYBLQWq1I97BacI9mqGIO1kHNQyJR0NwENmAYWINg0iIsSk4GwI/JqC4dvCO5mgmNmZFNtJfGAQ7LaNnJ5cVxpNXX8L/m88dbI/0AbIAlgKtF3qSwSXNYIwZF5UNYIs61d2JcF1sCRVkmitAa+ylC4ApxkFrVaMhSkouWCZjgslHIlElUsr13M9LxCbrkqBG0yZeUccVrTBvsNbQs430K73SRTKa7dbUtWWOG5J6LZh5jHYIxvLPiEtqIB5jXBMVIYxvimcGMnUGB+guwaTyUKayNJXC/ThGO5rYngcu4dz4kgxL1GBOctEbSI1Wrf657Y0O6c+3+Y1Ry5cC2CabxzW/YHN32D6rhNNUH7FGrxIPUNlMoqoPmNj92j9g3YG7zQwh04mJtDgzxMYd/D958+z+/ux7P70ee7v778eTub3k/AGPw1pNnfj4BTngz9syQxZPrfwtA8RU0TL9m8Tz29w54+PG829egje73GfxQ00ejqjL2Gf/8Dcb+ru93Re31uDZrs5PZXuN157Efa90G2u3A7C+vUvjtj70D7PsheB+2bDwJa7duC9+gvv54c+yacH+jPP82xEa+uxvqt/G+N/7bdOcAzDLued7SOVCo6DKG+uNeyX0I1e5h47aALRhfNLrj7q1ur8sEid9AEo/bBRjjleSfVHfJJ0O43xiWPa9UNley8uu2Tg3dW3eiCBRSqG/Nfre6ri8PqDNcf4VXn5PHsOw==
\ No newline at end of file
diff --git a/dependency-injection/docs/inject-demo-classdiagram.png b/dependency-injection/docs/inject-demo-classdiagram.png
new file mode 100644
index 0000000000..9996fdc733
Binary files /dev/null and b/dependency-injection/docs/inject-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/inject-field-demo-classdiagram.png b/dependency-injection/docs/inject-field-demo-classdiagram.png
new file mode 100644
index 0000000000..e63b6e5f42
Binary files /dev/null and b/dependency-injection/docs/inject-field-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/inject-field-demo-classdiagram.xml b/dependency-injection/docs/inject-field-demo-classdiagram.xml
new file mode 100644
index 0000000000..147c545a2d
--- /dev/null
+++ b/dependency-injection/docs/inject-field-demo-classdiagram.xml
@@ -0,0 +1 @@
+7Vhdb9s4EPw1fuwhtqK0eYw/ctdDeijqHO7uyWAkWmJLcX0UFcf99d2llpZkKUiKOHkobBiGOVx+zcxybY2iWfHwuxWb/BOkUo8mZ+nDKJqPJpMPkwg/CdjVQBxf1kBmVVpD4wZYqu+SwTNGK5XKshPoALRTmy6YgDEycR1MWAvbbtgadHfVjcjCig2wTITuo/+o1OXhWBcN/odUWR5WHl/w+e5E8i2zUBlebzSJ1v5VdxcizMUHLXORwrYFRQuk1QLgzPSteJhJTdQG2upx14/07vdtpeG9PTEg7MPtwtllilRwE6zLIQMj9KJBp/58kmY4w1buCo1fx/gVF7W7fxn3jf+o8Vvsm+kVKUOzbqS5zZWp0WuFO6qHfJXO7dgNonKAULODG4ANr1PvmTb66LEZKqGyCUdh2xtJ2Exy1Ps95ehkCYXELWOIlVo4dd+dXbCnsn1cwyt+YWqHaeal74WueNJrJXX60XxF985lAT0Vyq0qtDBEd4vgNRgXtKG20CpDGucJnltaBO6ldQp9fMUdjjibJrnS6Y3YQUXnLh2aNLSmOVj1HacVYQ3sto5FQMO3I5Y0krWyssSYz4FyGllDN6IkgGIS0FpsSnW333CB5CszBeeg4KBwUvLBDDTgMZCAkDZBbDqY5OvlMbn7QoYB7HK+jUJz26R2FDOWt9P6gsGXSM83YUv6d9TrlR/PJaZCKk2CO7tC+MreKWeF3bU6Dp2BNHjdGleUzsI3Gbgz4F2zbtHJUHCLlmuaYdgr5UYkymQ3PmZ+3iBfmBiCtrlycok47WmLJYAyFedba5/guUpx7/6mcMKJWn7SegPKOE9mPMU30juj2yHGc82wjSqGNr4p3LoZGDyfwHE4TKK3tpL89Txb+Lzr24J9EK7zp3wQ4l5ig/OeDXrCanWY7rWwoQL5C+CnVS1QC39rs4y3/hZ956fvSB31pSboUEIt7qT+DKVyCmh+W8ceSPsG6sXM4FPqfXi5ePGAeHiEszVd4k2qrj79vbxdTRerj3/9uZjdLuarZZUksizXldac4feAk55S+rVMEW7st0hpnqLliudc36fCfsTCHr/vVvaIk70l/76It+W/PEJh978de4XdX491qi+dxRw7JfsLkt2n2M/U70G1j5HsbKxT/T6aegP1e1C9I9Rv/nPeq98OOEdP+foWig8U51fL1zHvrqX5F/l/pbCUPUNhX/Ae5ZGooscTVBQP6vVzpOYMJl2PUALPw88bJvmS/3C2SB7k+AgVcNx/rBEeu/wi5EYHvy8u+hUnEHl0cvsPDn4xcuMD58avRi42m0eqvq/12Dpa/AA=
\ No newline at end of file
diff --git a/dependency-injection/docs/inject-name-demo-classdiagram.png b/dependency-injection/docs/inject-name-demo-classdiagram.png
new file mode 100644
index 0000000000..96a6a3425e
Binary files /dev/null and b/dependency-injection/docs/inject-name-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/inject-name-demo-classdiagram.xml b/dependency-injection/docs/inject-name-demo-classdiagram.xml
new file mode 100644
index 0000000000..5a8bb9f8c4
--- /dev/null
+++ b/dependency-injection/docs/inject-name-demo-classdiagram.xml
@@ -0,0 +1 @@
+7VhZbxs3EP41AtqHFDqydvOoy20KJwgiF2meDHp3pGXC5ahcyrLy6zPkDrWnYQVe5yGQIAjit8Njvm8OiYPJPHv4y4ht+g4TUIPxMHkYTBaD8fjP8YQ+HXAogCh6UwAbI5MCGpXASn4DBoeM7mQCec3QIiort3UwRq0htjVMGIP7utkaVX3XrdiEHUtgFQvVRj/JxKbBrYsS/xvkJg07jy7YvzsRf90Y3GnebzCerP2reJyJsBY7mqciwX0FmiyJVoNIK7tv2cMclKM20FbMu3rk6fHcBjSf7YkJ4Rz2EHyHhKjgIRqb4ga1UMsSnXn/wK0wpFFqM0VfR/SVNjWH/xj3g89u8Efkh8nUKeNW3YK+SaUu0CtJJyqmfAFrDxwNYmeRoPIE14hb3qc4szvoo24zlOPOxGxFYx9IwmyArS6PlFMkA2ZARyYTA0pYeV9fXXBMbY52Ja/0hantppm3vhdqx4teSVDJ7PBeZPBWf6EYXkCGLS3yvcyU0I70Cs1r1DYo5MZCyQ2RuYjJezAE3IOxkqJ5yg+sY24Wp1Il1+KAO+d9bilUw2iWopHfaFkR9qDHxrIUFPZVi5WbyYoZyMnmQyDezSyga5E7wNnEqJTY5vLueOCMJJB6htZixkbBUxcNc1RIbhABIXmC5M4x4CLzmOhtOUNVKiZwSQqRvy/ze3LJOqWV3H7Dds+Rn6thRf5XNNSkfbIASoYEdEzHmhI4NXfSGmEOlQfNqCAKvGZlROTW4FcIvGn0EbOuUMlQiBQFa7dCd5zkWxFLvbn2NovXJfKRWXHQPpUWVoS7M+2pCbhcpfXWyqd4KhM6u68VVlhRSO903qLU1lMZzehN5M5dfYjIrzmNScEwprczN3aOmvwTNI+mAcXVHlxsnRYSXtF2SHAQhIL+VBAEu+cEwetWELSEVbKZ6oWwoQf55P9hVTPSwtdtlvHG19FXfvma1JO21A5qSqjEHagPmEsr0a1vCtuGtD9BvYgZfEo9TvzniBd1iEcuNHP49t2/q5vb2fL27ft/lvOb5eJ2jsZQdVec3itriN1zRr9YTFycWNb7yGheohIUn8FONdoUzCl1/Nzde+zuUWjUob+P2rX9+LO71uC5Oz8nEvzvyFaD94XynPc95b2X80c6eafafeQ995NzJ+9NvY5O3qleD52c/6i3OrnFIkd/+/2csT9F845O/WIZO+LTVVT/CP/vJHWzExT2Pe9RHh1V7rLC9cVGyz5Fas5hp2sPXXDU7IIRp0yF5UB8jeQe/uWO2rcc4RbmF2E3umywe9FRt16K3fYlwi/G7njYYHfY0dP7YZeG5R2rf1a5x54svwM=
\ No newline at end of file
diff --git a/dependency-injection/docs/inject-qualifier-demo-classdiagram.png b/dependency-injection/docs/inject-qualifier-demo-classdiagram.png
new file mode 100644
index 0000000000..1ffe6453cb
Binary files /dev/null and b/dependency-injection/docs/inject-qualifier-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/inject-qualifier-demo-classdiagram.xml b/dependency-injection/docs/inject-qualifier-demo-classdiagram.xml
new file mode 100644
index 0000000000..ec122afe71
--- /dev/null
+++ b/dependency-injection/docs/inject-qualifier-demo-classdiagram.xml
@@ -0,0 +1 @@
+7Vptb+I4EP41le4+bEUIUPZjeenenrqn3tLT3X6qTGIS7zox5zil7K/fcTLTvHbhFOAkBEKAx87EM88zL7G4cqfRywfN1uEn5XN51e/5L1fu7KrfH/dd+LSCbS4Y9VAQaOHnIqcQLMR3jsIeSlPh86Sy0CgljVhXhZ6KY+6ZioxprTbVZSslq3dds4DuWAgWHpNN6d/CNyGZNSrkv3ERhHRnZ/Q+n1ky71ugVRrj/a767ip75dMRI11oaBIyX21KIncObtVKgWb7K3qZcmldS27Lr7t7Y/Z135rHuLcdF9A+zJZs5z64AodKm1AFKmZyXkgnmX3caujBKDSRhJ8O/ISb6u0/KM8GX+zgepgN/VuLjNW65vFjKOJceidgR/klX7kxW2QDS40CUbGDe6XWeJ+mlWh4olLtoR0wznjDdMBx1U0ushaWLkPPfOAq4rBlWKC5ZEY8V8nAkFPB67rCr/ADXdvuZtzLM5MpKr0TXPp/pkyKleD6Y/wVaDzjkWrAkWxEJFls/V7y9ErFhkCyY9ATgD9nHniEaxA8c20EEPoWJ4x13sQLhfTv2Val1iOJAbbSaBIqLb6DWkb3gGltEA1gfnnFwl6JoGmewJoHAsNemYvuWWIFdo2npGTrRCxfNxwBLCKeKGNUhIvIUkuIqZIKzAAHUPz8BHVrK8fU8waiNIt0x7REw00R4+4NysJKfKOwCwcwA5Y48M5mSL5iqQToISZ8Hnuws1sQ3+qlMJrpbWmiP5IWJ188w8/A/gQFIxZZYONlkn2xiPs1XdUVP1EMBpR0N4gILs5oUpAwMVp94wRVrDKSrkrooYjIKfnKaminZrJmnoiD+2zNbFBIPiMOVrQJheELkNs9baD02AwB+lYySyyh8MGiLEMZZljONkuttRKxybAbTuANaE5tVhqCXVMYA2loDG+7XJupisE+BtfBZRyovOGWzi0spODezUKkHZWRXbQbDLqzDlWUWNcAVop6dsmBpcqX5Zv/jGoEWGTVAmF8zLL3u0x9BWq3CbUV1SGUbMnlg0qEEcrq1/naGrQnQI+Q2oXeuDt4DhLlDKvzsFmdHYTi9OUZN1MJEjCjB6VZltLp06e/Fo9Pk/nTxz9+n08f57OnRep5PElWqZTbX37NU/ezArWX5Lln+HUt4WPs6XZFo4vltwtNMBpLNGmtppcG7ngN3IgenKiDQ1hL8DujFvjfH6CBQ6bVGrisLuWRvzAaQu4S+/vGPsVTl8apFW1a1wVtLN+Xxulg6A3Rg7vQO0DjhKcxjYJuVB6jVKsvEXtkzAnfU0Ssg23cobvl6xuoMqWO2bnuuWMSPHAtYKe2ZGNf/dpIL6WyNfaYXbRDh6OlNhq5f/oumjZT7o9iZUKuL23Siduk4bjaJrmDZhz2e20nXSTsRITmceelU+r2lLQ/A95ulVoBP0jibR5tXnqljvi1NEut+B3ilKntjPDSLf0fUdvSLh0vapvPs5/5v6mAorYHxFnpe9OR1le2ubHlsVa598Eaw9gCe4BiOKgXw2Zotbakh6iEzafIM/XxsObj8Qmd3Hzao1b5TLzr0vEVpYnmoSc58tDOJR3n69xhzbkt6eFozm0+MZ0bc2u516FgPYV3m48h50ZdSqlE3eHRvAvD4l9J2Vzpn1/u/Ac=
\ No newline at end of file
diff --git a/dependency-injection/docs/resource-demo-classdiagram.png b/dependency-injection/docs/resource-demo-classdiagram.png
new file mode 100644
index 0000000000..1f0a41a19e
Binary files /dev/null and b/dependency-injection/docs/resource-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/resource-field-demo-classdiagram.png b/dependency-injection/docs/resource-field-demo-classdiagram.png
new file mode 100644
index 0000000000..0d6207d09a
Binary files /dev/null and b/dependency-injection/docs/resource-field-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/resource-field-demo-classdiagram.xml b/dependency-injection/docs/resource-field-demo-classdiagram.xml
new file mode 100644
index 0000000000..44c742f2bc
--- /dev/null
+++ b/dependency-injection/docs/resource-field-demo-classdiagram.xml
@@ -0,0 +1 @@
+7Vhtb+I4EP41SHcftgICtP1YoN1bqXtalZ7u7lPlJiZx1/HkHANlf/3OOGOSEPpyonfaOxUhFD8ejz3zzItDL5rljx+tKLLPkEjdG/aTx1407w2HZ8MIfwnYVsB4fF4BqVVJBQ1qYKG+SQb7jK5UIsuWoAPQThVtMAZjZOxamLAWNm2xJej2roVIw441sIiF7qK/q8RlwaxJjf8iVZqFnQcTtu9exF9TCyvD+/WG0dJ/qulcBF1saJmJBDYNKLpEt1oA1ExP+eNManJtcFu17uqJ2d25rTR8tucX4BQtWAu9YtN7w4nGpdMCH1J6uFJSJzeyhJWN5SfzgP5WYOYyhyCK6nfSbJbbBleWG5VrYXA0zVyuERzg4xKMW7AQjYVWqcHnGM8tLQJraZ1CQi54wkGBaJwpnVyLLazIutKht8NomoFV31CtCHvgtHUcW6PzlsSCViLcR9TKEmW+BJfRygq6FiUBJBOD1qIo1f3uwLmwqTJTcA5yFgqWXimtZ6ABzUAHBP6Da5rcMF1kq+TU8RBz9VFCLp3dokiY5bDhtBpxmm3qGI1GLJI14/OUBQXnRbrTXMcGPnB4HA4VVtEIlQ+U4XIpVtqhzQheIPAg1uJEwYlH9oMBzfRU1YFQOgtfZXCXAR8oy4YHGQoBouWSNBwOj7IQsTLptZeZj2rkhn1B0CZTTi4QpzNtsHwhBqhvqX0iZipJJKqcWnDCiYpxorcAZZz333iKX3TzrH8y7o3RrhmOkbgwxi+JWzcDg/YJXIfLJIbTRlJIHYiEkIcvR0KgngvOS9RHXLKOYX50oEjsEavVfoZXxIbq6XP+b7OaIxe0Q6Dxllief/DqW1RHXaoJ2qdQi3upv0CpqIIhZivZPWr/BfbOxq9j7+x48ninFnloQr/QaFko6xfGkKvQK3eff1vc3l19+nV+N69T+6efq+ReA6p9T+p/KizOX1nPx4wdExennbh4tnL/GG0cL2A/SBvvkHqgsz/Zxk/77T4+CNfBBvGDyaF6wCF1DPHcON6reTNtX6DTJ8uTaRteC15ib8SN9KhbGJ+uwZZM8N2Fh2hoBikYoS9rFD2HLySSNJDfGrSigXb7B+N+8CcNsOLRMLmgVynSWkhzmykqoIhSYvCSB+nclnNTrBxQ1d2d4Bo8wbRPdWY66PMZg3b5ftS6cWL+p/J5IqzU2L3Wbe1Hubn7YnQj/1opLCmv6H++8DzZZSgiyVlUnPbq5msaIacNdb03KEXjvVeKwaQbzIdiOVSso5zcfaXoRvd/2rtR6NTh3te9tQdHvrlzu7f2/5lzJ6fszRC6I1bx9t7FYf2fjJ9r/O8VXX4H
\ No newline at end of file
diff --git a/dependency-injection/docs/resource-method-byname-demo-classdiagram.png b/dependency-injection/docs/resource-method-byname-demo-classdiagram.png
new file mode 100644
index 0000000000..c5cd0c0fcb
Binary files /dev/null and b/dependency-injection/docs/resource-method-byname-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/resource-method-demo-classdiagram.png b/dependency-injection/docs/resource-method-demo-classdiagram.png
new file mode 100644
index 0000000000..6be7dbbeea
Binary files /dev/null and b/dependency-injection/docs/resource-method-demo-classdiagram.png differ
diff --git a/dependency-injection/docs/resource-method-demo-classdiagram.xml b/dependency-injection/docs/resource-method-demo-classdiagram.xml
new file mode 100644
index 0000000000..94b39279fc
--- /dev/null
+++ b/dependency-injection/docs/resource-method-demo-classdiagram.xml
@@ -0,0 +1 @@
+3Vhbb+I6EP41SN0HECGQbh8boNuutkerltXZ84QMcRL3OHFqHAr99R0749y4qCpdqV0eQvx5PJ755mJDxx0nm2+SZPGtCCjvDPrBpuNOOoPB14ELTw1sC2A0uiiASLKggJwKuGfPFME+ojkL6KohqITgimVNcCnSlC5VAyNSiqemWCh4c9eMRHbHCrhfEr6L/ssCFVu3vAq/piyK7c6Oh/4tyPL/SIo8xf06Azc0n2I6IVYXOrqKSSCeapA7BVqlEKBZvyWbMeWaWktbse7qwGxpt6Qp2nZ8ATq0UlvrOg2ACRwKqWIRiZTwaYX6xj2qFfRhFKuEw6sDr7Cn3P5G3Az+04PeyAyDSx0YrTWj6SxmaYFeMTCoWPJAldpiMpBcCYAqC34IkeE+hc3a0INeI7QSuVyiFKakIjKiKDUqGYdEpiKhYDKISMqJYuumdoIpFZVyFa3wgsweCAtGe014jlrv6GPOJOR4m39FN2BdnVaQYs9kYQQ0TZlgqTLWjPzOaAII4SwCOidL8J9KANZUKgbpfIkTCQsCEztOFpT7ZZKOBRcgD/vaNLXsag0Uy7lZbGhJlcN13k0+7TKKivo9DAK2he6wGL6acNT8UzNQqe2CeE2r01IgwnAFEW/HqzTvVSFEw2sR7Aw8riOVNeLnPea6dv0E0kyn+CXM9rMNPA210AE03lU6mfXcsDanQ9/FWOo5DGepE94i/DY7LyxwS6FKgjtapPtN+gBhYiKd0ERYWfCvFC/Xa90NBKTAnSYWg1QfMrDpH3B8yKw3EcJpCFIlI23dXX2Y0JDkXEHDAM1a8oGsSY+JnkHe2QMLaIwkECw/Xaz0l5VZZSTd6yhnKe3GeDpoM52ezpXWVjVn5re/7mdzfzq/+ef7dDybTuZjISWEkEPOl14V+zXtPNGGsy/F5FpAlh/faR+tO8CJ5hwh+6j/BQYlPqk4PavnxlvdbHXmdlM1NVz23iKBfQFSITfnXGhONj8UqcJDzYEOZsZXJGEQXXdyTfmaaq3Nln+wB++ccQd7rWPbM3ZFF4dP1X3G7SNmQ2PWnSN4yoFnDtaP2i0PtI2d9vhhm+En7N+vNflTl5xna8xeRIa7Ned4e2ru4h1K7nyn5Owd+MS7JVzEMXv0ghb3+wMErXXJ0mhmbuxwyXsXdodavsbuBTaZGrm25dW5tdgp3OKPu7+XW8/emW3men+MXBhWP2+Li3j1F4I7fQE=
\ No newline at end of file
diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml
new file mode 100644
index 0000000000..46f57e512e
--- /dev/null
+++ b/dependency-injection/pom.xml
@@ -0,0 +1,81 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ dependency-injection
+ 0.0.1-SNAPSHOT
+ war
+
+ @Resource vs @Inject vs @Autowired
+ Accompanying the demonstration of the use of the annotations related to injection mechanisms, namely @Resource, @Inject, and @Autowired
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.10.19
+
+
+ org.springframework
+ spring-test
+ 4.2.6.RELEASE
+
+
+ org.springframework
+ spring-core
+ 4.2.6.RELEASE
+
+
+ org.springframework
+ spring-beans
+ 4.2.6.RELEASE
+
+
+ org.springframework
+ spring-context
+ 4.2.6.RELEASE
+
+
+ javax.inject
+ javax.inject
+ 1
+
+
+
+
+
+
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/*Demo.java
+
+
+
+
+
+
+
+
+ java.net
+ https://maven.java.net/content/repositories/releases/
+
+
+
diff --git a/dependency-injection/src/test/java/com/baeldung/autowired/FieldAutowiredDemo.java b/dependency-injection/src/test/java/com/baeldung/autowired/FieldAutowiredDemo.java
new file mode 100644
index 0000000000..c71365097f
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/autowired/FieldAutowiredDemo.java
@@ -0,0 +1,27 @@
+package com.baeldung.autowired;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.dependency.ArbitraryDependency;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Autowired-Type.xml"})
+public class FieldAutowiredDemo {
+
+ @Autowired
+ private ArbitraryDependency fieldDependency;
+
+ @Test
+ public void fieldDependency_MUST_BE_AUTOWIRED_Correctly() {
+ assertNotNull(fieldDependency);
+ assertEquals("Arbitrary Dependency", fieldDependency.toString());
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/autowired/FieldAutowiredNameDemo.java b/dependency-injection/src/test/java/com/baeldung/autowired/FieldAutowiredNameDemo.java
new file mode 100644
index 0000000000..c11ed5286a
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/autowired/FieldAutowiredNameDemo.java
@@ -0,0 +1,27 @@
+package com.baeldung.autowired;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.dependency.ArbitraryDependency;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Autowired-Name.xml"})
+public class FieldAutowiredNameDemo {
+
+ @Autowired
+ private ArbitraryDependency autowiredFieldDependency;
+
+ @Test
+ public void autowiredFieldDependency_MUST_BE_AUTOWIRED_Correctly() {
+ assertNotNull(autowiredFieldDependency);
+ assertEquals("Arbitrary Dependency", autowiredFieldDependency.toString());
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/autowired/FieldQualifierAutowiredDemo.java b/dependency-injection/src/test/java/com/baeldung/autowired/FieldQualifierAutowiredDemo.java
new file mode 100644
index 0000000000..5afce6ab6a
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/autowired/FieldQualifierAutowiredDemo.java
@@ -0,0 +1,39 @@
+package com.baeldung.autowired;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.dependency.ArbitraryDependency;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Autowired-Qualifier.xml"})
+public class FieldQualifierAutowiredDemo {
+
+ @Autowired
+ @Qualifier("autowiredFieldDependency")
+ private ArbitraryDependency fieldDependency1;
+
+ @Autowired
+ @Qualifier("anotherAutowiredFieldDependency")
+ private ArbitraryDependency fieldDependency2;
+
+ @Test
+ public void fieldDependency1_MUST_BE_AUTOWIRED_Correctly() {
+ assertNotNull(fieldDependency1);
+ assertEquals("Arbitrary Dependency", fieldDependency1.toString());
+ }
+
+ @Test
+ public void fieldDependency2_MUST_BE_AUTOWIRED_Correctly() {
+ assertNotNull(fieldDependency2);
+ assertEquals("Another Arbitrary Dependency", fieldDependency2.toString());
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/dependency/AnotherArbitraryDependency.java b/dependency-injection/src/test/java/com/baeldung/dependency/AnotherArbitraryDependency.java
new file mode 100644
index 0000000000..27ba03f6e8
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/dependency/AnotherArbitraryDependency.java
@@ -0,0 +1,10 @@
+package com.baeldung.dependency;
+
+public class AnotherArbitraryDependency extends ArbitraryDependency {
+
+ private final String label = "Another Arbitrary Dependency";
+
+ public String toString() {
+ return label;
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/dependency/ArbitraryDependency.java b/dependency-injection/src/test/java/com/baeldung/dependency/ArbitraryDependency.java
new file mode 100644
index 0000000000..bab289777c
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/dependency/ArbitraryDependency.java
@@ -0,0 +1,10 @@
+package com.baeldung.dependency;
+
+public class ArbitraryDependency {
+
+ private final String label = "Arbitrary Dependency";
+
+ public String toString() {
+ return label;
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/dependency/YetAnotherArbitraryDependency.java b/dependency-injection/src/test/java/com/baeldung/dependency/YetAnotherArbitraryDependency.java
new file mode 100644
index 0000000000..1f59500ec5
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/dependency/YetAnotherArbitraryDependency.java
@@ -0,0 +1,10 @@
+package com.baeldung.dependency;
+
+public class YetAnotherArbitraryDependency extends ArbitraryDependency {
+
+ private final String label = "Yet Another Arbitrary Dependency";
+
+ public String toString() {
+ return label;
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/inject/FieldByNameInjectDemo.java b/dependency-injection/src/test/java/com/baeldung/inject/FieldByNameInjectDemo.java
new file mode 100644
index 0000000000..a670ee8313
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/inject/FieldByNameInjectDemo.java
@@ -0,0 +1,30 @@
+package com.baeldung.inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.dependency.ArbitraryDependency;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Inject-Name.xml"})
+public class FieldByNameInjectDemo {
+
+ @Inject
+ @Named("yetAnotherFieldInjectDependency")
+ private ArbitraryDependency yetAnotherFieldInjectDependency;
+
+ @Test
+ public void yetAnotherFieldInjectDependency_MUST_BE_INJECTED_Correctly() {
+ assertNotNull(yetAnotherFieldInjectDependency);
+ assertEquals("Yet Another Arbitrary Dependency", yetAnotherFieldInjectDependency.toString());
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/inject/FieldInjectDemo.java b/dependency-injection/src/test/java/com/baeldung/inject/FieldInjectDemo.java
new file mode 100644
index 0000000000..df40e516ba
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/inject/FieldInjectDemo.java
@@ -0,0 +1,27 @@
+package com.baeldung.inject;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import javax.inject.Inject;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.dependency.ArbitraryDependency;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Inject-Type.xml"})
+public class FieldInjectDemo {
+
+ @Inject
+ private ArbitraryDependency inject1Dependency;
+
+ @Test
+ public void fieldDependency_MUST_BE_INJECTED_Successfully() {
+ assertNotNull(inject1Dependency);
+ assertEquals("Arbitrary Dependency", inject1Dependency.toString());
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/inject/FieldQualifierInjectDemo.java b/dependency-injection/src/test/java/com/baeldung/inject/FieldQualifierInjectDemo.java
new file mode 100644
index 0000000000..3cc9b643c7
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/inject/FieldQualifierInjectDemo.java
@@ -0,0 +1,40 @@
+package com.baeldung.inject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import javax.inject.Inject;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.dependency.ArbitraryDependency;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Inject-Qualifier.xml"})
+public class FieldQualifierInjectDemo {
+
+ @Inject
+ @Qualifier("defaultFile")
+ private ArbitraryDependency defaultDependency;
+
+ @Inject
+ @Qualifier("namedFile")
+ private ArbitraryDependency namedDependency;
+
+ @Test
+ public void defaultDependency_MUST_BE_INJECTED_Successfully() {
+ assertNotNull(defaultDependency);
+ assertEquals("Arbitrary Dependency", defaultDependency.toString());
+ }
+
+ @Test
+ public void namedDependency_MUST_BE_INJECTED_Correctly() {
+ assertNotNull(defaultDependency);
+ assertEquals("Another Arbitrary Dependency", namedDependency.toString());
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/FieldResourceInjectionDemo.java b/dependency-injection/src/test/java/com/baeldung/resource/FieldResourceInjectionDemo.java
new file mode 100644
index 0000000000..fbb378d672
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/FieldResourceInjectionDemo.java
@@ -0,0 +1,25 @@
+package com.baeldung.resource;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-NameType.xml"})
+public class FieldResourceInjectionDemo {
+
+ @Resource(name="namedFile")
+ private File defaultFile;
+
+ @Test
+ public void plainResourceAnnotation_MUST_FIND_DefaultFile() {
+ assertNotNull(defaultFile);
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/MethodByQualifierResourceDemo.java b/dependency-injection/src/test/java/com/baeldung/resource/MethodByQualifierResourceDemo.java
new file mode 100644
index 0000000000..fcca34dc2f
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/MethodByQualifierResourceDemo.java
@@ -0,0 +1,43 @@
+package com.baeldung.resource;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-Qualifier.xml"})
+public class MethodByQualifierResourceDemo {
+
+ private File arbDependency;
+ private File anotherArbDependency;
+
+ @Test
+ public void dependencies_MUST_BE_INJECTED_Correctly() {
+ assertNotNull(arbDependency);
+ assertEquals("namedFile.txt", arbDependency.getName());
+ assertNotNull(anotherArbDependency);
+ assertEquals("defaultFile.txt", anotherArbDependency.getName());
+ }
+
+ @Resource
+ @Qualifier("namedFile")
+ public void setArbDependency(File arbDependency) {
+ this.arbDependency = arbDependency;
+ }
+
+ @Resource
+ @Qualifier("defaultFile")
+ public void setAnotherArbDependency(File anotherArbDependency) {
+ this.anotherArbDependency = anotherArbDependency;
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/MethodByTypeResourceDemo.java b/dependency-injection/src/test/java/com/baeldung/resource/MethodByTypeResourceDemo.java
new file mode 100644
index 0000000000..af6a805bd9
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/MethodByTypeResourceDemo.java
@@ -0,0 +1,30 @@
+package com.baeldung.resource;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-NameType.xml"})
+public class MethodByTypeResourceDemo {
+
+ private File defaultFile;
+
+ @Resource
+ protected void setDefaultFile(File defaultFile) {
+ this.defaultFile = defaultFile;
+ }
+
+ @Test
+ public void defaultFile_MUST_BE_INJECTED_Correctly() {
+ assertNotNull(defaultFile);
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/MethodResourceInjectionDemo.java b/dependency-injection/src/test/java/com/baeldung/resource/MethodResourceInjectionDemo.java
new file mode 100644
index 0000000000..d746fd4d85
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/MethodResourceInjectionDemo.java
@@ -0,0 +1,29 @@
+package com.baeldung.resource;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-NameType.xml"})
+public class MethodResourceInjectionDemo {
+
+ private File defaultFile;
+
+ @Resource(name="namedFile")
+ protected void setDefaultFile(File defaultFile) {
+ this.defaultFile = defaultFile;
+ }
+
+ @Test
+ public void defaultFile_MUST_BE_INJECTED_Correctly() {
+ assertNotNull(defaultFile);
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/NamedResourceTest.java b/dependency-injection/src/test/java/com/baeldung/resource/NamedResourceTest.java
new file mode 100644
index 0000000000..8b218dfe98
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/NamedResourceTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.resource;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-NameType.xml"})
+public class NamedResourceTest {
+
+ @Resource(name="namedFile")
+ private File testFile;
+
+ @Test
+ public void namedResource_MUST_FIND_SPECIFIED_File() {
+ assertNotNull(testFile);
+ assertTrue(testFile.getName().equals("namedFile.txt"));
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/QualifierResourceInjectionDemo.java b/dependency-injection/src/test/java/com/baeldung/resource/QualifierResourceInjectionDemo.java
new file mode 100644
index 0000000000..0aaa2085d5
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/QualifierResourceInjectionDemo.java
@@ -0,0 +1,35 @@
+package com.baeldung.resource;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-Qualifier.xml"})
+public class QualifierResourceInjectionDemo {
+
+ @Resource
+ private File defaultFile;
+
+ @Resource
+ @Qualifier("namedFile")
+ private File namedFile;
+
+ @Test
+ public void defaultFile_MUST_BE_Valid() {
+ assertNotNull(defaultFile);
+ }
+
+ @Test
+ public void namedFile_MUST_BE_Valid() {
+ assertNotNull(namedFile);
+ }
+}
diff --git a/dependency-injection/src/test/java/com/baeldung/resource/SetterResourceInjectionDemo.java b/dependency-injection/src/test/java/com/baeldung/resource/SetterResourceInjectionDemo.java
new file mode 100644
index 0000000000..25dd5bb9ff
--- /dev/null
+++ b/dependency-injection/src/test/java/com/baeldung/resource/SetterResourceInjectionDemo.java
@@ -0,0 +1,29 @@
+package com.baeldung.resource;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.annotation.Resource;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={
+ "/applicationContextTest-@Resource-NameType.xml"})
+public class SetterResourceInjectionDemo {
+
+ private File defaultFile;
+
+ @Resource
+ protected void setDefaultFile(File defaultFile) {
+ this.defaultFile = defaultFile;
+ }
+
+ @Test
+ public void setter_MUST_INJECT_Resource() {
+ assertNotNull(defaultFile);
+ }
+}
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Name.xml b/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Name.xml
new file mode 100644
index 0000000000..d7fe3abcb3
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Name.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Qualifier.xml b/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Qualifier.xml
new file mode 100644
index 0000000000..d7fe3abcb3
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Qualifier.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Type.xml b/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Type.xml
new file mode 100644
index 0000000000..c65b85ccf4
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Autowired-Type.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Inject-Name.xml b/dependency-injection/src/test/resources/applicationContextTest-@Inject-Name.xml
new file mode 100644
index 0000000000..610e8687a7
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Inject-Name.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Inject-Qualifier.xml b/dependency-injection/src/test/resources/applicationContextTest-@Inject-Qualifier.xml
new file mode 100644
index 0000000000..627ec37914
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Inject-Qualifier.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Inject-Type.xml b/dependency-injection/src/test/resources/applicationContextTest-@Inject-Type.xml
new file mode 100644
index 0000000000..405164e603
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Inject-Type.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Resource-NameType.xml b/dependency-injection/src/test/resources/applicationContextTest-@Resource-NameType.xml
new file mode 100644
index 0000000000..82cbe97157
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Resource-NameType.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/dependency-injection/src/test/resources/applicationContextTest-@Resource-Qualifier.xml b/dependency-injection/src/test/resources/applicationContextTest-@Resource-Qualifier.xml
new file mode 100644
index 0000000000..1680a6f66a
--- /dev/null
+++ b/dependency-injection/src/test/resources/applicationContextTest-@Resource-Qualifier.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/gatling/pom.xml b/gatling/pom.xml
new file mode 100644
index 0000000000..273797d76c
--- /dev/null
+++ b/gatling/pom.xml
@@ -0,0 +1,110 @@
+
+
+ 4.0.0
+ org.baeldung
+ gatling
+ 1.0-SNAPSHOT
+
+
+ 1.8
+ 1.8
+ 2.11.7
+ UTF-8
+ 2.2.0
+ 3.2.2
+
+
+
+
+
+ io.gatling
+ gatling-app
+ ${gatling.version}
+
+
+ io.gatling
+ gatling-recorder
+ ${gatling.version}
+
+
+ io.gatling.highcharts
+ gatling-charts-highcharts
+ ${gatling.version}
+
+
+ org.scala-lang
+ scala-library
+ ${scala.version}
+
+
+
+
+
+
+ io.gatling.highcharts
+ gatling-charts-highcharts
+
+
+ io.gatling
+ gatling-app
+
+
+ io.gatling
+ gatling-recorder
+
+
+ org.scala-lang
+ scala-library
+
+
+
+
+ src/test/scala
+
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+ ${scala-maven-plugin.version}
+
+
+
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+
+
+
+ testCompile
+
+
+
+ -Ybackend:GenBCode
+ -Ydelambdafy:method
+ -target:jvm-1.8
+ -deprecation
+ -feature
+ -unchecked
+ -language:implicitConversions
+ -language:postfixOps
+
+
+
+
+
+
+ io.gatling
+ gatling-maven-plugin
+ ${gatling.version}
+
+
+ test
+ execute
+
+
+
+
+
+
diff --git a/gatling/src/test/resources/gatling.conf b/gatling/src/test/resources/gatling.conf
new file mode 100644
index 0000000000..8bfa0ed366
--- /dev/null
+++ b/gatling/src/test/resources/gatling.conf
@@ -0,0 +1,127 @@
+#########################
+# Gatling Configuration #
+#########################
+
+# This file contains all the settings configurable for Gatling with their default values
+
+gatling {
+ core {
+ #outputDirectoryBaseName = "" # The prefix for each simulation result folder (then suffixed by the report generation timestamp)
+ #runDescription = "" # The description for this simulation run, displayed in each report
+ #encoding = "utf-8" # Encoding to use throughout Gatling for file and string manipulation
+ #simulationClass = "" # The FQCN of the simulation to run (when used in conjunction with noReports, the simulation for which assertions will be validated)
+ #mute = false # When set to true, don't ask for simulation name nor run description (currently only used by Gatling SBT plugin)
+ #elFileBodiesCacheMaxCapacity = 200 # Cache size for request body EL templates, set to 0 to disable
+ #rawFileBodiesCacheMaxCapacity = 200 # Cache size for request body Raw templates, set to 0 to disable
+ #rawFileBodiesInMemoryMaxSize = 1000 # Below this limit, raw file bodies will be cached in memory
+
+ extract {
+ regex {
+ #cacheMaxCapacity = 200 # Cache size for the compiled regexes, set to 0 to disable caching
+ }
+ xpath {
+ #cacheMaxCapacity = 200 # Cache size for the compiled XPath queries, set to 0 to disable caching
+ }
+ jsonPath {
+ #cacheMaxCapacity = 200 # Cache size for the compiled jsonPath queries, set to 0 to disable caching
+ #preferJackson = false # When set to true, prefer Jackson over Boon for JSON-related operations
+ }
+ css {
+ #cacheMaxCapacity = 200 # Cache size for the compiled CSS selectors queries, set to 0 to disable caching
+ }
+ }
+
+ directory {
+ #data = user-files/data # Folder where user's data (e.g. files used by Feeders) is located
+ #bodies = user-files/bodies # Folder where bodies are located
+ #simulations = user-files/simulations # Folder where the bundle's simulations are located
+ #reportsOnly = "" # If set, name of report folder to look for in order to generate its report
+ #binaries = "" # If set, name of the folder where compiles classes are located: Defaults to GATLING_HOME/target.
+ #results = results # Name of the folder where all reports folder are located
+ }
+ }
+ charting {
+ #noReports = false # When set to true, don't generate HTML reports
+ #maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports
+ #useGroupDurationMetric = false # Switch group timings from cumulated response time to group duration.
+ indicators {
+ #lowerBound = 800 # Lower bound for the requests' response time to track in the reports and the console summary
+ #higherBound = 1200 # Higher bound for the requests' response time to track in the reports and the console summary
+ #percentile1 = 50 # Value for the 1st percentile to track in the reports, the console summary and Graphite
+ #percentile2 = 75 # Value for the 2nd percentile to track in the reports, the console summary and Graphite
+ #percentile3 = 95 # Value for the 3rd percentile to track in the reports, the console summary and Graphite
+ #percentile4 = 99 # Value for the 4th percentile to track in the reports, the console summary and Graphite
+ }
+ }
+ http {
+ #fetchedCssCacheMaxCapacity = 200 # Cache size for CSS parsed content, set to 0 to disable
+ #fetchedHtmlCacheMaxCapacity = 200 # Cache size for HTML parsed content, set to 0 to disable
+ #perUserCacheMaxCapacity = 200 # Per virtual user cache size, set to 0 to disable
+ #warmUpUrl = "http://gatling.io" # The URL to use to warm-up the HTTP stack (blank means disabled)
+ #enableGA = true # Very light Google Analytics, please support
+ ssl {
+ keyStore {
+ #type = "" # Type of SSLContext's KeyManagers store
+ #file = "" # Location of SSLContext's KeyManagers store
+ #password = "" # Password for SSLContext's KeyManagers store
+ #algorithm = "" # Algorithm used SSLContext's KeyManagers store
+ }
+ trustStore {
+ #type = "" # Type of SSLContext's TrustManagers store
+ #file = "" # Location of SSLContext's TrustManagers store
+ #password = "" # Password for SSLContext's TrustManagers store
+ #algorithm = "" # Algorithm used by SSLContext's TrustManagers store
+ }
+ }
+ ahc {
+ #keepAlive = true # Allow pooling HTTP connections (keep-alive header automatically added)
+ #connectTimeout = 60000 # Timeout when establishing a connection
+ #pooledConnectionIdleTimeout = 60000 # Timeout when a connection stays unused in the pool
+ #readTimeout = 60000 # Timeout when a used connection stays idle
+ #maxRetry = 2 # Number of times that a request should be tried again
+ #requestTimeout = 60000 # Timeout of the requests
+ #acceptAnyCertificate = true # When set to true, doesn't validate SSL certificates
+ #httpClientCodecMaxInitialLineLength = 4096 # Maximum length of the initial line of the response (e.g. "HTTP/1.0 200 OK")
+ #httpClientCodecMaxHeaderSize = 8192 # Maximum size, in bytes, of each request's headers
+ #httpClientCodecMaxChunkSize = 8192 # Maximum length of the content or each chunk
+ #webSocketMaxFrameSize = 10240000 # Maximum frame payload size
+ #sslEnabledProtocols = [TLSv1.2, TLSv1.1, TLSv1] # Array of enabled protocols for HTTPS, if empty use the JDK defaults
+ #sslEnabledCipherSuites = [] # Array of enabled cipher suites for HTTPS, if empty use the JDK defaults
+ #sslSessionCacheSize = 0 # SSLSession cache size, set to 0 to use JDK's default
+ #sslSessionTimeout = 0 # SSLSession timeout in seconds, set to 0 to use JDK's default (24h)
+ #useOpenSsl = false # if OpenSSL should be used instead of JSSE (requires tcnative jar)
+ #useNativeTransport = false # if native transport should be used instead of Java NIO (requires netty-transport-native-epoll, currently Linux only)
+ #usePooledMemory = true # if Gatling should use pooled memory
+ #tcpNoDelay = true
+ #soReuseAddress = false
+ #soLinger = -1
+ #soSndBuf = -1
+ #soRcvBuf = -1
+ }
+ dns {
+ #queryTimeout = 5000 # Timeout of each DNS query in millis
+ #maxQueriesPerResolve = 3 # Maximum allowed number of DNS queries for a given name resolution
+ }
+ }
+ data {
+ #writers = [console, file] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite, jdbc)
+ console {
+ #light = false # When set to true, displays a light version without detailed request stats
+ }
+ file {
+ #bufferSize = 8192 # FileDataWriter's internal data buffer size, in bytes
+ }
+ leak {
+ #noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
+ }
+ graphite {
+ #light = false # only send the all* stats
+ #host = "localhost" # The host where the Carbon server is located
+ #port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle)
+ #protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
+ #rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite
+ #bufferSize = 8192 # GraphiteDataWriter's internal data buffer size, in bytes
+ #writeInterval = 1 # GraphiteDataWriter's write interval, in seconds
+ }
+ }
+}
diff --git a/gatling/src/test/resources/logback.xml b/gatling/src/test/resources/logback.xml
new file mode 100644
index 0000000000..b9ba6255a0
--- /dev/null
+++ b/gatling/src/test/resources/logback.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gatling/src/test/resources/recorder.conf b/gatling/src/test/resources/recorder.conf
new file mode 100644
index 0000000000..969b9e8668
--- /dev/null
+++ b/gatling/src/test/resources/recorder.conf
@@ -0,0 +1,53 @@
+recorder {
+ core {
+ #mode = "Proxy"
+ #encoding = "utf-8" # The encoding used for reading/writing request bodies and the generated simulation
+ #outputFolder = "" # The folder where generated simulation will we written
+ #package = "" # The package's name of the generated simulation
+ #className = "RecordedSimulation" # The name of the generated Simulation class
+ #thresholdForPauseCreation = 100 # The minimum time, in milliseconds, that must pass between requests to trigger a pause creation
+ #saveConfig = false # When set to true, the configuration from the Recorder GUI overwrites this configuration
+ #headless = false # When set to true, run the Recorder in headless mode instead of the GUI
+ #harFilePath = "" # The path of the HAR file to convert
+ }
+ filters {
+ #filterStrategy = "Disabled" # The selected filter resources filter strategy (currently supported : "Disabled", "BlackList", "WhiteList")
+ #whitelist = [] # The list of ressources patterns that are part of the Recorder's whitelist
+ #blacklist = [] # The list of ressources patterns that are part of the Recorder's blacklist
+ }
+ http {
+ #automaticReferer = true # When set to false, write the referer + enable 'disableAutoReferer' in the generated simulation
+ #followRedirect = true # When set to false, write redirect requests + enable 'disableFollowRedirect' in the generated simulation
+ #removeCacheHeaders = true # When set to true, removes from the generated requests headers leading to request caching
+ #inferHtmlResources = true # When set to true, add inferred resources + set 'inferHtmlResources' with the configured blacklist/whitelist in the generated simulation
+ #checkResponseBodies = false # When set to true, save response bodies as files and add raw checks in the generated simulation
+ }
+ proxy {
+ #port = 8000 # Local port used by Gatling's Proxy for HTTP/HTTPS
+ https {
+ #mode = "SelfSignedCertificate" # The selected "HTTPS mode" (currently supported : "SelfSignedCertificate", "ProvidedKeyStore", "GatlingCertificateAuthority", "CustomCertificateAuthority")
+ keyStore {
+ #path = "" # The path of the custom key store
+ #password = "" # The password for this key store
+ #type = "JKS" # The type of the key store (currently supported: "JKS")
+ }
+ certificateAuthority {
+ #certificatePath = "" # The path of the custom certificate
+ #privateKeyPath = "" # The certificate's private key path
+ }
+ }
+ outgoing {
+ #host = "" # The outgoing proxy's hostname
+ #username = "" # The username to use to connect to the outgoing proxy
+ #password = "" # The password corresponding to the user to use to connect to the outgoing proxy
+ #port = 0 # The HTTP port to use to connect to the outgoing proxy
+ #sslPort = 0 # If set, The HTTPS port to use to connect to the outgoing proxy
+ }
+ }
+ netty {
+ #maxInitialLineLength = 10000 # Maximum length of the initial line of the response (e.g. "HTTP/1.0 200 OK")
+ #maxHeaderSize = 20000 # Maximum size, in bytes, of each request's headers
+ #maxChunkSize = 8192 # Maximum length of the content or each chunk
+ #maxContentLength = 100000000 # Maximum length of the aggregated content of each response
+ }
+}
diff --git a/gatling/src/test/scala/Engine.scala b/gatling/src/test/scala/Engine.scala
new file mode 100644
index 0000000000..32c85fbe45
--- /dev/null
+++ b/gatling/src/test/scala/Engine.scala
@@ -0,0 +1,13 @@
+import io.gatling.app.Gatling
+import io.gatling.core.config.GatlingPropertiesBuilder
+
+object Engine extends App {
+
+ val props = new GatlingPropertiesBuilder
+ props.dataDirectory(IDEPathHelper.dataDirectory.toString)
+ props.resultsDirectory(IDEPathHelper.resultsDirectory.toString)
+ props.bodiesDirectory(IDEPathHelper.bodiesDirectory.toString)
+ props.binariesDirectory(IDEPathHelper.mavenBinariesDirectory.toString)
+
+ Gatling.fromMap(props.build)
+}
diff --git a/gatling/src/test/scala/IDEPathHelper.scala b/gatling/src/test/scala/IDEPathHelper.scala
new file mode 100644
index 0000000000..0abf6a42ef
--- /dev/null
+++ b/gatling/src/test/scala/IDEPathHelper.scala
@@ -0,0 +1,22 @@
+import java.nio.file.Path
+
+import io.gatling.commons.util.PathHelper._
+
+object IDEPathHelper {
+
+ val gatlingConfUrl: Path = getClass.getClassLoader.getResource("gatling.conf").toURI
+ val projectRootDir = gatlingConfUrl.ancestor(3)
+
+ val mavenSourcesDirectory = projectRootDir / "src" / "test" / "scala"
+ val mavenResourcesDirectory = projectRootDir / "src" / "test" / "resources"
+ val mavenTargetDirectory = projectRootDir / "target"
+ val mavenBinariesDirectory = mavenTargetDirectory / "test-classes"
+
+ val dataDirectory = mavenResourcesDirectory / "data"
+ val bodiesDirectory = mavenResourcesDirectory / "bodies"
+
+ val recorderOutputDirectory = mavenSourcesDirectory
+ val resultsDirectory = mavenTargetDirectory / "gatling"
+
+ val recorderConfigFile = mavenResourcesDirectory / "recorder.conf"
+}
diff --git a/gatling/src/test/scala/Recorder.scala b/gatling/src/test/scala/Recorder.scala
new file mode 100644
index 0000000000..6ad320618b
--- /dev/null
+++ b/gatling/src/test/scala/Recorder.scala
@@ -0,0 +1,12 @@
+import io.gatling.recorder.GatlingRecorder
+import io.gatling.recorder.config.RecorderPropertiesBuilder
+
+object Recorder extends App {
+
+ val props = new RecorderPropertiesBuilder
+ props.simulationOutputFolder(IDEPathHelper.recorderOutputDirectory.toString)
+ props.simulationPackage("org.baeldung")
+ props.bodiesFolder(IDEPathHelper.bodiesDirectory.toString)
+
+ GatlingRecorder.fromMap(props.build, Some(IDEPathHelper.recorderConfigFile))
+}
diff --git a/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala b/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala
new file mode 100644
index 0000000000..cdbef1bf3c
--- /dev/null
+++ b/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala
@@ -0,0 +1,46 @@
+package org.baeldung
+
+import scala.concurrent.duration._
+
+import io.gatling.core.Predef._
+import io.gatling.http.Predef._
+import io.gatling.jdbc.Predef._
+
+class RecordedSimulation extends Simulation {
+
+ val httpProtocol = http
+ .baseURL("http://computer-database.gatling.io")
+ .inferHtmlResources(BlackList(""".*\.css""", """.*\.js""", """.*\.ico"""), WhiteList())
+ .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
+ .acceptEncodingHeader("gzip, deflate")
+ .acceptLanguageHeader("it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3")
+ .userAgentHeader("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0")
+
+
+
+
+
+ val scn = scenario("RecordedSimulation")
+ .exec(http("request_0")
+ .get("/"))
+ .pause(5)
+ .exec(http("request_1")
+ .get("/computers?f=amstrad"))
+ .pause(4)
+ .exec(http("request_2")
+ .get("/computers/412"))
+ .pause(2)
+ .exec(http("request_3")
+ .get("/"))
+ .pause(2)
+ .exec(http("request_4")
+ .get("/computers?p=1"))
+ .pause(1)
+ .exec(http("request_5")
+ .get("/computers?p=2"))
+ .pause(2)
+ .exec(http("request_6")
+ .get("/computers?p=3"))
+
+ setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
+}
diff --git a/httpclient/.settings/org.eclipse.jdt.ui.prefs b/httpclient/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 471e9b0d81..0000000000
--- a/httpclient/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,55 +0,0 @@
-#Sat Jan 21 23:04:06 EET 2012
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=true
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=true
-sp_cleanup.correct_indentation=true
-sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=true
-sp_cleanup.make_local_variable_final=true
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=false
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=false
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=true
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=true
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=false
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=true
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=true
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/httpclient/src/test/java/org/baeldung/httpclient/SandboxTest.java b/httpclient/src/test/java/org/baeldung/httpclient/SandboxTest.java
new file mode 100644
index 0000000000..eb3084f941
--- /dev/null
+++ b/httpclient/src/test/java/org/baeldung/httpclient/SandboxTest.java
@@ -0,0 +1,146 @@
+package org.baeldung.httpclient;
+
+import java.io.IOException;
+
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.MalformedChallengeException;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.auth.DigestScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.http.util.EntityUtils;
+import org.junit.Test;
+
+public class SandboxTest {
+
+ @Test
+ public final void whenInterestingDigestAuthScenario_then200OK() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException {
+ final HttpHost targetHost = new HttpHost("httpbin.org", 80, "http");
+
+ // set up the credentials to run agains the server
+ final CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials("user", "passwd"));
+
+ // This endpoint need fake cookie to work properly
+ final CookieStore cookieStore = new BasicCookieStore();
+ final BasicClientCookie cookie = new BasicClientCookie("fake", "fake_value");
+ cookie.setDomain("httpbin.org");
+ cookie.setPath("/");
+ cookieStore.addCookie(cookie);
+
+ // We need a first run to get a 401 to seed the digest auth
+
+ // Make a client using those creds
+ final CloseableHttpClient client = HttpClients.custom().setDefaultCookieStore(cookieStore).setDefaultCredentialsProvider(credsProvider).build();
+
+ // And make a call to the URL we are after
+ final HttpGet httpget = new HttpGet("http://httpbin.org/digest-auth/auth/user/passwd");
+
+ // Create a context to use
+ final HttpClientContext context = HttpClientContext.create();
+
+ // Get a response from the sever (expect a 401!)
+ final HttpResponse authResponse = client.execute(targetHost, httpget, context);
+
+ // Pull out the auth header that came back from the server
+ final Header challenge = authResponse.getHeaders("WWW-Authenticate")[0];
+
+ // Lets use a digest scheme to solve it
+ final DigestScheme digest = new DigestScheme();
+ digest.processChallenge(challenge);
+
+ // Make a header with the solution based upon user/password and what the digest got out of the initial 401 reponse
+ final Header solution = digest.authenticate(new UsernamePasswordCredentials("user", "passwd"), httpget, context);
+
+ // Need an auth cache to use the new digest we made
+ final AuthCache authCache = new BasicAuthCache();
+ authCache.put(targetHost, digest);
+
+ // Add the authCache and thus solved digest to the context
+ context.setAuthCache(authCache);
+
+ // Pimp up our http get with the solved header made by the digest
+ httpget.addHeader(solution);
+
+ // use it!
+ System.out.println("Executing request " + httpget.getRequestLine() + " to target " + targetHost);
+
+ for (int i = 0; i < 3; i++) {
+ final CloseableHttpResponse responseGood = client.execute(targetHost, httpget, context);
+
+ try {
+ System.out.println("----------------------------------------");
+ System.out.println(responseGood.getStatusLine());
+ System.out.println(EntityUtils.toString(responseGood.getEntity()));
+ } finally {
+ responseGood.close();
+ }
+ }
+ client.close();
+ }
+
+ // This test needs module spring-security-rest-digest-auth to be running
+ @Test
+ public final void whenWeKnowDigestParameters_thenNo401Status() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException {
+ final HttpHost targetHost = new HttpHost("localhost", 8080, "http");
+
+ final CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user1", "user1Pass"));
+
+ final CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
+
+ final HttpGet httpget = new HttpGet("http://localhost:8080/spring-security-rest-digest-auth/api/foos/1");
+
+ final HttpClientContext context = HttpClientContext.create();
+ // == make it preemptive
+ final AuthCache authCache = new BasicAuthCache();
+ final DigestScheme digestAuth = new DigestScheme();
+ digestAuth.overrideParamter("realm", "Custom Realm Name");
+ digestAuth.overrideParamter("nonce", "nonce value goes here");
+ authCache.put(targetHost, digestAuth);
+ context.setAuthCache(authCache);
+ // == end
+ System.out.println("Executing The Request knowing the digest parameters ==== ");
+ final HttpResponse authResponse = client.execute(targetHost, httpget, context);
+ System.out.println(authResponse.toString());
+ client.close();
+ }
+
+ // This test needs module spring-security-rest-digest-auth to be running
+ @Test
+ public final void whenDoNotKnowParameters_thenOnlyOne401() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException {
+ final HttpClientContext context = HttpClientContext.create();
+ final HttpHost targetHost = new HttpHost("localhost", 8080, "http");
+ final CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user1", "user1Pass"));
+ final CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
+
+ final HttpGet httpget = new HttpGet("http://localhost:8080/spring-security-rest-digest-auth/api/foos/1");
+ System.out.println("Executing The Request NOT knowing the digest parameters ==== ");
+ final HttpResponse tempResponse = client.execute(targetHost, httpget, context);
+ System.out.println(tempResponse.toString());
+
+ for (int i = 0; i < 3; i++) {
+ System.out.println("No more Challenges or 401");
+ final CloseableHttpResponse authResponse = client.execute(targetHost, httpget, context);
+ System.out.println(authResponse.toString());
+ authResponse.close();
+ }
+ client.close();
+ }
+}
diff --git a/jee7schedule/pom.xml b/jee7schedule/pom.xml
new file mode 100644
index 0000000000..627b8723e3
--- /dev/null
+++ b/jee7schedule/pom.xml
@@ -0,0 +1,311 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ jee7schedule
+ 1.0-SNAPSHOT
+ JavaEE 7 Arquillian Archetype Sample
+ war
+
+
+ 1.7
+ 3.0.0
+
+ 4.11
+ 7.0
+
+ 1.1.4.Final
+
+ 8.0.0.Final
+
+
+
+ ${maven.min.version}
+
+
+
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ ${version.arquillian_core}
+ import
+ pom
+
+
+
+
+
+
+ javax
+ javaee-api
+ ${version.javaee_api}
+ provided
+
+
+
+ junit
+ junit
+ ${version.junit}
+ test
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-container
+ test
+
+
+ com.jayway.awaitility
+ awaitility
+ 1.6.0
+ test
+
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-impl-maven
+ test
+ jar
+
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-impl-maven-archive
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+
+ ${java.min.version}
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 2.1.1
+
+ false
+
+
+
+
+
+
+
+
+ wildfly-managed-arquillian
+
+ true
+
+
+ standalone-full.xml
+ ${project.build.directory}/wildfly-${version.wildfly}
+
+
+
+ io.undertow
+ undertow-websockets-jsr
+ 1.0.0.Beta25
+ test
+
+
+ org.jboss.resteasy
+ resteasy-client
+ 3.0.5.Final
+ test
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ 3.0.5.Final
+ test
+
+
+ org.jboss.resteasy
+ resteasy-json-p-provider
+ 3.0.5.Final
+ test
+
+
+ org.wildfly
+ wildfly-arquillian-container-managed
+ ${version.wildfly}
+ test
+
+
+
+
+
+ maven-dependency-plugin
+ 2.8
+
+ ${maven.test.skip}
+
+
+
+ unpack
+ process-test-classes
+
+ unpack
+
+
+
+
+ org.wildfly
+ wildfly-dist
+ ${version.wildfly}
+ zip
+ false
+ ${project.build.directory}
+
+
+
+
+
+
+
+ maven-surefire-plugin
+ 2.17
+
+
+ ${project.build.directory}/wildfly-${version.wildfly}
+
+
+
+
+
+
+
+ wildfly-remote-arquillian
+
+
+ io.undertow
+ undertow-websockets-jsr
+ 1.0.0.Beta25
+ test
+
+
+ org.jboss.resteasy
+ resteasy-client
+ 3.0.5.Final
+ test
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ 3.0.5.Final
+ test
+
+
+ org.jboss.resteasy
+ resteasy-json-p-provider
+ 3.0.5.Final
+ test
+
+
+ org.wildfly
+ wildfly-arquillian-container-remote
+ ${version.wildfly}
+ test
+
+
+
+
+ glassfish-embedded-arquillian
+
+
+ org.glassfish.main.extras
+ glassfish-embedded-all
+ 4.0
+ test
+
+
+ org.glassfish
+ javax.json
+ 1.0.4
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-client
+ 1.3
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-container-grizzly-client
+ 1.3
+ test
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ 2.4
+ test
+
+
+ org.jboss.arquillian.container
+ arquillian-glassfish-embedded-3.1
+ 1.0.0.CR4
+ test
+
+
+
+
+ glassfish-remote-arquillian
+
+
+ org.glassfish
+ javax.json
+ 1.0.4
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-client
+ 1.3
+ test
+
+
+ org.glassfish.tyrus
+ tyrus-container-grizzly-client
+ 1.3
+ test
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ 2.4
+ test
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-jackson
+ 2.4
+ test
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-processing
+ 2.4
+ test
+
+
+ org.jboss.arquillian.container
+ arquillian-glassfish-remote-3.1
+ 1.0.0.CR4
+ test
+
+
+
+
+
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/AutomaticTimerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/AutomaticTimerBean.java
new file mode 100644
index 0000000000..373d962f02
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/AutomaticTimerBean.java
@@ -0,0 +1,27 @@
+package com.baeldung.timer;
+
+import javax.ejb.Schedule;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+import java.util.Date;
+
+
+@Startup
+@Singleton
+public class AutomaticTimerBean {
+
+
+ @Inject
+ Event event;
+
+ /**
+ * This method will be called every 10 second and will fire an @TimerEvent
+ */
+ @Schedule(hour = "*", minute = "*", second = "*/10", info = "Every 10 second timer")
+ public void printDate() {
+ event.fire(new TimerEvent("TimerEvent sent at :" + new Date()));
+ }
+
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java
new file mode 100644
index 0000000000..a466682dea
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java
@@ -0,0 +1,20 @@
+package com.baeldung.timer;
+
+import javax.ejb.*;
+
+/**
+ * Created by ccristianchiovari on 5/2/16.
+ */
+@Singleton
+public class FixedDelayTimerBean {
+
+ @EJB
+ private WorkerBean workerBean;
+
+ @Lock(LockType.READ)
+ @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
+ public void atSchedule() throws InterruptedException {
+ workerBean.doTimerWork();
+ }
+
+}
\ No newline at end of file
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java
new file mode 100644
index 0000000000..c1c210c8ac
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java
@@ -0,0 +1,31 @@
+package com.baeldung.timer;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.ejb.*;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+
+/**
+ * author: Cristian Chiovari
+ */
+@Startup
+@Singleton
+public class ProgrammaticAtFixedRateTimerBean {
+
+ @Inject
+ Event event;
+
+ @Resource
+ TimerService timerService;
+
+ @PostConstruct
+ public void initialize() {
+ timerService.createTimer(0,1000, "Every second timer");
+ }
+
+ @Timeout
+ public void programmaticTimout(Timer timer) {
+ event.fire(new TimerEvent(timer.getInfo().toString()));
+ }
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java
new file mode 100644
index 0000000000..d2dba1239f
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java
@@ -0,0 +1,39 @@
+package com.baeldung.timer;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.ejb.*;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+
+/**
+ * author: Jacek Jackowiak
+ */
+@Startup
+@Singleton
+public class ProgrammaticTimerBean {
+
+ @Inject
+ Event event;
+
+ @Resource
+ TimerService timerService;
+
+ @PostConstruct
+ public void initialize() {
+ ScheduleExpression scheduleExpression = new ScheduleExpression()
+ .hour("*")
+ .minute("*")
+ .second("*/5");
+
+ TimerConfig timerConfig = new TimerConfig();
+ timerConfig.setInfo("Every 5 second timer");
+
+ timerService.createCalendarTimer(scheduleExpression, timerConfig);
+ }
+
+ @Timeout
+ public void programmaticTimout(Timer timer) {
+ event.fire(new TimerEvent(timer.getInfo().toString()));
+ }
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java
new file mode 100644
index 0000000000..9a1ebcdc57
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java
@@ -0,0 +1,31 @@
+package com.baeldung.timer;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.ejb.*;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+
+/**
+ * author: Cristian Chiovari
+ */
+@Startup
+@Singleton
+public class ProgrammaticWithInitialFixedDelayTimerBean {
+
+ @Inject
+ Event event;
+
+ @Resource
+ TimerService timerService;
+
+ @PostConstruct
+ public void initialize() {
+ timerService.createTimer(10000l,5000l, "Delay 10 seconds then every 5 second timer");
+ }
+
+ @Timeout
+ public void programmaticTimout(Timer timer) {
+ event.fire(new TimerEvent(timer.getInfo().toString()));
+ }
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ScheduleTimerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/ScheduleTimerBean.java
new file mode 100644
index 0000000000..09fb95c889
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/ScheduleTimerBean.java
@@ -0,0 +1,27 @@
+package com.baeldung.timer;
+
+import javax.ejb.Schedule;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.ejb.Timer;
+import javax.enterprise.event.Event;
+import javax.inject.Inject;
+
+
+@Startup
+@Singleton
+public class ScheduleTimerBean {
+
+ @Inject
+ Event event;
+
+ @Schedule(hour = "*", minute = "*", second = "*/5", info = "Every 5 second timer")
+ public void automaticallyScheduled(Timer timer) {
+ fireEvent(timer);
+ }
+
+
+ private void fireEvent(Timer timer) {
+ event.fire(new TimerEvent(timer.getInfo().toString()));
+ }
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/TimerEvent.java b/jee7schedule/src/main/java/com/baeldung/timer/TimerEvent.java
new file mode 100644
index 0000000000..e430cfc1b1
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/TimerEvent.java
@@ -0,0 +1,27 @@
+package com.baeldung.timer;
+
+public class TimerEvent {
+
+ private String eventInfo;
+ private long time = System.currentTimeMillis();
+
+ public TimerEvent(String s) {
+ this.eventInfo = s;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public String getEventInfo() {
+ return eventInfo;
+ }
+
+ @Override
+ public String toString() {
+ return "TimerEvent {" +
+ "eventInfo='" + eventInfo + '\'' +
+ ", time=" + time +
+ '}';
+ }
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/TimerEventListener.java b/jee7schedule/src/main/java/com/baeldung/timer/TimerEventListener.java
new file mode 100644
index 0000000000..c89677213a
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/TimerEventListener.java
@@ -0,0 +1,26 @@
+package com.baeldung.timer;
+
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.enterprise.event.Observes;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * This class will listen to all TimerEvent and will collect them
+ */
+@Startup
+@Singleton
+public class TimerEventListener {
+
+ final List events = new CopyOnWriteArrayList<>();
+
+ public void listen(@Observes TimerEvent event) {
+ System.out.println("event = " + event);
+ events.add(event);
+ }
+
+ public List getEvents() {
+ return events;
+ }
+}
diff --git a/jee7schedule/src/main/java/com/baeldung/timer/WorkerBean.java b/jee7schedule/src/main/java/com/baeldung/timer/WorkerBean.java
new file mode 100644
index 0000000000..c1f781e95e
--- /dev/null
+++ b/jee7schedule/src/main/java/com/baeldung/timer/WorkerBean.java
@@ -0,0 +1,33 @@
+package com.baeldung.timer;
+
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Singleton;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created by cristianchiovari on 5/2/16.
+ */
+@Singleton
+public class WorkerBean {
+
+ private AtomicBoolean busy = new AtomicBoolean(false);
+
+ @Lock(LockType.READ)
+ public void doTimerWork() throws InterruptedException {
+
+ System.out.println("Timer method called but not started yet !");
+
+ if (!busy.compareAndSet(false, true)) {
+ return;
+ }
+
+ try {
+ System.out.println("Timer work started");
+ Thread.sleep(12000);
+ System.out.println("Timer work done");
+ } finally {
+ busy.set(false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/jee7schedule/src/main/webapp/WEB-INF/beans.xml b/jee7schedule/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/jee7schedule/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java b/jee7schedule/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java
new file mode 100644
index 0000000000..df922b28df
--- /dev/null
+++ b/jee7schedule/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java
@@ -0,0 +1,66 @@
+package com.baeldung.timer;
+
+import com.jayway.awaitility.Awaitility;
+import org.hamcrest.Matchers;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static com.jayway.awaitility.Awaitility.to;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+
+@RunWith(Arquillian.class)
+public class AutomaticTimerBeanTest {
+
+ //the @AutomaticTimerBean has a method called every 10 seconds
+ //testing the difference ==> 100000
+ final static long TIMEOUT = 10000l;
+
+ //the tolerance accepted , so if between two consecutive calls there has to be at least 9 or max 11 seconds.
+ //because the timer service is not intended for real-time applications so it will not be exactly 10 seconds
+ final static long TOLERANCE = 1000l;
+
+ @Inject
+ TimerEventListener timerEventListener;
+
+ @Deployment
+ public static WebArchive deploy() {
+ File[] jars = Maven.resolver().loadPomFromFile("pom.xml")
+ .resolve("com.jayway.awaitility:awaitility")
+ .withTransitivity().asFile();
+
+ //only @AutomaticTimerBean is deployed not the other timers
+ return ShrinkWrap.create(WebArchive.class)
+ .addAsLibraries(jars)
+ .addClasses(WithinWindowMatcher.class, TimerEvent.class, TimerEventListener.class, AutomaticTimerBean.class);
+ }
+
+
+
+ @Test
+ public void should_receive_two_pings() {
+ Awaitility.setDefaultTimeout(30, TimeUnit.SECONDS);
+ //the test will wait here until two events are triggered
+ await().untilCall(to(timerEventListener.getEvents()).size(), equalTo(2));
+
+ TimerEvent firstEvent = timerEventListener.getEvents().get(0);
+ TimerEvent secondEvent = timerEventListener.getEvents().get(1);
+
+ long delay = secondEvent.getTime() - firstEvent.getTime();
+ System.out.println("Actual timeout = " + delay);
+
+ //ensure that the delay between the events is more or less 10 seconds (no real time precision)
+ assertThat(delay, Matchers.is(WithinWindowMatcher.withinWindow(TIMEOUT, TOLERANCE)));
+ }
+}
diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java b/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java
new file mode 100644
index 0000000000..76c0e3e5b8
--- /dev/null
+++ b/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java
@@ -0,0 +1,56 @@
+package com.baeldung.timer;
+
+import com.jayway.awaitility.Awaitility;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static com.jayway.awaitility.Awaitility.to;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+
+@RunWith(Arquillian.class)
+public class ProgrammaticAtFixedRateTimerBeanTest {
+
+ final static long TIMEOUT = 1000;
+ final static long TOLERANCE = 500l;
+
+ @Inject
+ TimerEventListener timerEventListener;
+
+ @Deployment
+ public static WebArchive deploy() {
+ File[] jars = Maven.resolver().loadPomFromFile("pom.xml")
+ .resolve("com.jayway.awaitility:awaitility")
+ .withTransitivity().asFile();
+
+ return ShrinkWrap.create(WebArchive.class)
+ .addAsLibraries(jars)
+ .addClasses(WithinWindowMatcher.class, TimerEvent.class, TimerEventListener.class, ProgrammaticAtFixedRateTimerBean.class);
+ }
+
+ @Test
+ public void should_receive_ten_pings() {
+
+ Awaitility.setDefaultTimeout(30, TimeUnit.SECONDS);
+
+ await().untilCall(to(timerEventListener.getEvents()).size(), equalTo(10));
+ TimerEvent firstEvent = timerEventListener.getEvents().get(0);
+ TimerEvent secondEvent = timerEventListener.getEvents().get(1);
+
+ long delay = secondEvent.getTime() - firstEvent.getTime();
+ System.out.println("Actual timeout = " + delay);
+ assertThat(delay, is(WithinWindowMatcher.withinWindow(TIMEOUT, TOLERANCE)));
+ }
+}
\ No newline at end of file
diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java b/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java
new file mode 100644
index 0000000000..f93ba61fe3
--- /dev/null
+++ b/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java
@@ -0,0 +1,53 @@
+package com.baeldung.timer;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.io.File;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static com.jayway.awaitility.Awaitility.to;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+
+@RunWith(Arquillian.class)
+public class ProgrammaticTimerBeanTest {
+
+ final static long TIMEOUT = 5000l;
+ final static long TOLERANCE = 1000l;
+
+ @Inject
+ TimerEventListener timerEventListener;
+
+ @Deployment
+ public static WebArchive deploy() {
+ File[] jars = Maven.resolver().loadPomFromFile("pom.xml")
+ .resolve("com.jayway.awaitility:awaitility")
+ .withTransitivity().asFile();
+
+ return ShrinkWrap.create(WebArchive.class)
+ .addAsLibraries(jars)
+ .addClasses(WithinWindowMatcher.class, TimerEvent.class, TimerEventListener.class, ProgrammaticTimerBean.class);
+ }
+
+ @Test
+ public void should_receive_two_pings() {
+
+ await().untilCall(to(timerEventListener.getEvents()).size(), equalTo(2));
+
+ TimerEvent firstEvent = timerEventListener.getEvents().get(0);
+ TimerEvent secondEvent = timerEventListener.getEvents().get(1);
+
+ long delay = secondEvent.getTime() - firstEvent.getTime();
+ System.out.println("Actual timeout = " + delay);
+ assertThat(delay, is(WithinWindowMatcher.withinWindow(TIMEOUT, TOLERANCE)));
+ }
+}
\ No newline at end of file
diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java b/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java
new file mode 100644
index 0000000000..6764aa386d
--- /dev/null
+++ b/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.timer;
+
+import com.jayway.awaitility.Awaitility;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static com.jayway.awaitility.Awaitility.to;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+
+@RunWith(Arquillian.class)
+public class ProgrammaticWithFixedDelayTimerBeanTest {
+
+ final static long TIMEOUT = 15000l;
+ final static long TOLERANCE = 1000l;
+
+ @Inject
+ TimerEventListener timerEventListener;
+
+ @Deployment
+ public static WebArchive deploy() {
+ File[] jars = Maven.resolver().loadPomFromFile("pom.xml")
+ .resolve("com.jayway.awaitility:awaitility")
+ .withTransitivity().asFile();
+
+ return ShrinkWrap.create(WebArchive.class)
+ .addAsLibraries(jars)
+ .addClasses(WithinWindowMatcher.class, TimerEvent.class, TimerEventListener.class, ProgrammaticWithInitialFixedDelayTimerBean.class);
+ }
+
+ @Test
+ public void should_receive_two_pings() {
+
+ Awaitility.setDefaultTimeout(30, TimeUnit.SECONDS);
+
+ // 10 seconds pause so we get the startTime and it will trigger first event
+ long startTime = System.currentTimeMillis();
+
+ await().untilCall(to(timerEventListener.getEvents()).size(), equalTo(2));
+ TimerEvent firstEvent = timerEventListener.getEvents().get(0);
+ TimerEvent secondEvent = timerEventListener.getEvents().get(1);
+
+ long delay = secondEvent.getTime() - startTime;
+ System.out.println("Actual timeout = " + delay);
+
+ //apx 15 seconds = 10 delay + 2 timers (first after a pause of 10 seconds and the next others every 5 seconds)
+ assertThat(delay, is(WithinWindowMatcher.withinWindow(TIMEOUT, TOLERANCE)));
+ }
+}
\ No newline at end of file
diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java b/jee7schedule/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java
new file mode 100644
index 0000000000..7a5b043101
--- /dev/null
+++ b/jee7schedule/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java
@@ -0,0 +1,59 @@
+package com.baeldung.timer;
+
+import com.jayway.awaitility.Awaitility;
+import org.hamcrest.Matchers;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static com.jayway.awaitility.Awaitility.to;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+
+@RunWith(Arquillian.class)
+public class ScheduleTimerBeanTest {
+
+ final static long TIMEOUT = 5000l;
+ final static long TOLERANCE = 1000l;
+
+ @Inject
+ TimerEventListener timerEventListener;
+
+ @Deployment
+ public static WebArchive deploy() {
+ File[] jars = Maven.resolver().loadPomFromFile("pom.xml")
+ .resolve("com.jayway.awaitility:awaitility")
+ .withTransitivity().asFile();
+
+ return ShrinkWrap.create(WebArchive.class)
+ .addAsLibraries(jars)
+ .addClasses(WithinWindowMatcher.class, TimerEvent.class, TimerEventListener.class, ScheduleTimerBean.class);
+ }
+
+ @Test
+ public void should_receive_three_pings() {
+
+ Awaitility.setDefaultTimeout(30, TimeUnit.SECONDS);
+ await().untilCall(to(timerEventListener.getEvents()).size(), equalTo(3));
+
+ TimerEvent firstEvent = timerEventListener.getEvents().get(0);
+ TimerEvent secondEvent = timerEventListener.getEvents().get(1);
+ TimerEvent thirdEvent = timerEventListener.getEvents().get(2);
+
+ long delay = secondEvent.getTime() - firstEvent.getTime();
+ assertThat(delay, Matchers.is(WithinWindowMatcher.withinWindow(TIMEOUT, TOLERANCE)));
+ delay = thirdEvent.getTime() - secondEvent.getTime();
+ assertThat(delay, Matchers.is(WithinWindowMatcher.withinWindow(TIMEOUT, TOLERANCE)));
+
+ }
+}
diff --git a/jee7schedule/src/test/java/com/baeldung/timer/WithinWindowMatcher.java b/jee7schedule/src/test/java/com/baeldung/timer/WithinWindowMatcher.java
new file mode 100644
index 0000000000..91adca6042
--- /dev/null
+++ b/jee7schedule/src/test/java/com/baeldung/timer/WithinWindowMatcher.java
@@ -0,0 +1,30 @@
+package com.baeldung.timer;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+class WithinWindowMatcher extends BaseMatcher {
+ private final long timeout;
+ private final long tolerance;
+
+ public WithinWindowMatcher(long timeout, long tolerance) {
+ this.timeout = timeout;
+ this.tolerance = tolerance;
+ }
+
+ @Override
+ public boolean matches(Object item) {
+ final Long actual = (Long) item;
+ return Math.abs(actual - timeout) < tolerance;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public static Matcher withinWindow(final long timeout, final long tolerance) {
+ return new WithinWindowMatcher(timeout, tolerance);
+ }
+}
diff --git a/jooq-spring/.classpath b/jooq-spring/.classpath
deleted file mode 100644
index 9ae7bca0fc..0000000000
--- a/jooq-spring/.classpath
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/jooq-spring/.gitignore b/jooq-spring/.gitignore
new file mode 100644
index 0000000000..aba850c8e6
--- /dev/null
+++ b/jooq-spring/.gitignore
@@ -0,0 +1 @@
+/src/main/java/com/baeldung/jooq/introduction/db
\ No newline at end of file
diff --git a/jooq-spring/pom.xml b/jooq-spring/pom.xml
index 76198c4993..7a3ec0ac24 100644
--- a/jooq-spring/pom.xml
+++ b/jooq-spring/pom.xml
@@ -14,6 +14,19 @@
4.12
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 1.3.3.RELEASE
+ pom
+ import
+
+
+
+
@@ -40,6 +53,11 @@
spring-jdbc
${org.springframework.version}
+
+ org.springframework.boot
+ spring-boot-starter-jooq
+ 1.3.3.RELEASE
+
@@ -67,7 +85,7 @@
spring-test
${org.springframework.version}
test
-
+
diff --git a/jooq-spring/src/main/resources/application.properties b/jooq-spring/src/main/resources/application.properties
new file mode 100644
index 0000000000..2b32da2356
--- /dev/null
+++ b/jooq-spring/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+spring.datasource.url=jdbc:h2:~/jooq
+spring.datasource.username=sa
+spring.datasource.password=
\ No newline at end of file
diff --git a/jooq-spring/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java b/jooq-spring/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java
index 7bee21f077..8312f20c05 100644
--- a/jooq-spring/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java
+++ b/jooq-spring/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java
@@ -8,12 +8,12 @@ import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
public class ExceptionTranslator extends DefaultExecuteListener {
- private static final long serialVersionUID = 649359748808106775L;
@Override
public void exception(ExecuteContext context) {
SQLDialect dialect = context.configuration().dialect();
SQLExceptionTranslator translator = new SQLErrorCodeSQLExceptionTranslator(dialect.name());
+
context.exception(translator.translate("Access database using jOOQ", context.sql(), context.sqlException()));
}
}
\ No newline at end of file
diff --git a/jooq-spring/src/test/java/com/baeldung/jooq/introduction/PersistenceContext.java b/jooq-spring/src/test/java/com/baeldung/jooq/introduction/PersistenceContext.java
index ee34c00679..df628f9f78 100644
--- a/jooq-spring/src/test/java/com/baeldung/jooq/introduction/PersistenceContext.java
+++ b/jooq-spring/src/test/java/com/baeldung/jooq/introduction/PersistenceContext.java
@@ -1,6 +1,5 @@
package com.baeldung.jooq.introduction;
-import javax.sql.DataSource;
import org.h2.jdbcx.JdbcDataSource;
import org.jooq.SQLDialect;
import org.jooq.impl.DataSourceConnectionProvider;
@@ -17,11 +16,14 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
+import javax.sql.DataSource;
+
@Configuration
@ComponentScan({ "com.baeldung.jooq.introduction.db.public_.tables" })
@EnableTransactionManagement
@PropertySource("classpath:intro_config.properties")
public class PersistenceContext {
+
@Autowired
private Environment environment;
diff --git a/jooq-spring/src/test/java/com/baeldung/jooq/introduction/QueryTest.java b/jooq-spring/src/test/java/com/baeldung/jooq/introduction/QueryTest.java
index bc12dff5a0..68f975dd6d 100644
--- a/jooq-spring/src/test/java/com/baeldung/jooq/introduction/QueryTest.java
+++ b/jooq-spring/src/test/java/com/baeldung/jooq/introduction/QueryTest.java
@@ -1,8 +1,5 @@
package com.baeldung.jooq.introduction;
-import com.baeldung.jooq.introduction.db.public_.tables.Author;
-import com.baeldung.jooq.introduction.db.public_.tables.AuthorBook;
-import com.baeldung.jooq.introduction.db.public_.tables.Book;
import org.jooq.DSLContext;
import org.jooq.Record3;
import org.jooq.Result;
@@ -15,6 +12,9 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
+import static com.baeldung.jooq.introduction.db.public_.tables.Author.AUTHOR;
+import static com.baeldung.jooq.introduction.db.public_.tables.AuthorBook.AUTHOR_BOOK;
+import static com.baeldung.jooq.introduction.db.public_.tables.Book.BOOK;
import static org.junit.Assert.assertEquals;
@ContextConfiguration(classes = PersistenceContext.class)
@@ -25,61 +25,98 @@ public class QueryTest {
@Autowired
private DSLContext dsl;
- Author author = Author.AUTHOR;
- Book book = Book.BOOK;
- AuthorBook authorBook = AuthorBook.AUTHOR_BOOK;
-
@Test
public void givenValidData_whenInserting_thenSucceed() {
- dsl.insertInto(author).set(author.ID, 4).set(author.FIRST_NAME, "Herbert").set(author.LAST_NAME, "Schildt").execute();
- dsl.insertInto(book).set(book.ID, 4).set(book.TITLE, "A Beginner's Guide").execute();
- dsl.insertInto(authorBook).set(authorBook.AUTHOR_ID, 4).set(authorBook.BOOK_ID, 4).execute();
- Result> result = dsl.select(author.ID, author.LAST_NAME, DSL.count()).from(author).join(authorBook).on(author.ID.equal(authorBook.AUTHOR_ID)).join(book).on(authorBook.BOOK_ID.equal(book.ID))
- .groupBy(author.LAST_NAME).fetch();
+ dsl.insertInto(AUTHOR)
+ .set(AUTHOR.ID, 4)
+ .set(AUTHOR.FIRST_NAME, "Herbert")
+ .set(AUTHOR.LAST_NAME, "Schildt")
+ .execute();
+
+ dsl.insertInto(BOOK)
+ .set(BOOK.ID, 4)
+ .set(BOOK.TITLE, "A Beginner's Guide")
+ .execute();
+
+ dsl.insertInto(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 4)
+ .set(AUTHOR_BOOK.BOOK_ID, 4)
+ .execute();
+
+ final Result> result = dsl.select(AUTHOR.ID, AUTHOR.LAST_NAME, DSL.count())
+ .from(AUTHOR)
+ .join(AUTHOR_BOOK).on(AUTHOR.ID.equal(AUTHOR_BOOK.AUTHOR_ID))
+ .join(BOOK).on(AUTHOR_BOOK.BOOK_ID.equal(BOOK.ID))
+ .groupBy(AUTHOR.LAST_NAME).fetch();
assertEquals(3, result.size());
- assertEquals("Sierra", result.getValue(0, author.LAST_NAME));
+ assertEquals("Sierra", result.getValue(0, AUTHOR.LAST_NAME));
assertEquals(Integer.valueOf(2), result.getValue(0, DSL.count()));
- assertEquals("Schildt", result.getValue(2, author.LAST_NAME));
+ assertEquals("Schildt", result.getValue(2, AUTHOR.LAST_NAME));
assertEquals(Integer.valueOf(1), result.getValue(2, DSL.count()));
}
@Test(expected = DataAccessException.class)
public void givenInvalidData_whenInserting_thenFail() {
- dsl.insertInto(authorBook).set(authorBook.AUTHOR_ID, 4).set(authorBook.BOOK_ID, 5).execute();
+ dsl.insertInto(AUTHOR_BOOK).set(AUTHOR_BOOK.AUTHOR_ID, 4).set(AUTHOR_BOOK.BOOK_ID, 5).execute();
}
@Test
public void givenValidData_whenUpdating_thenSucceed() {
- dsl.update(author).set(author.LAST_NAME, "Baeldung").where(author.ID.equal(3)).execute();
- dsl.update(book).set(book.TITLE, "Building your REST API with Spring").where(book.ID.equal(3)).execute();
- dsl.insertInto(authorBook).set(authorBook.AUTHOR_ID, 3).set(authorBook.BOOK_ID, 3).execute();
- Result> result = dsl.select(author.ID, author.LAST_NAME, book.TITLE).from(author).join(authorBook).on(author.ID.equal(authorBook.AUTHOR_ID)).join(book).on(authorBook.BOOK_ID.equal(book.ID)).where(author.ID.equal(3))
+ dsl.update(AUTHOR)
+ .set(AUTHOR.LAST_NAME, "Baeldung")
+ .where(AUTHOR.ID.equal(3))
+ .execute();
+
+ dsl.update(BOOK)
+ .set(BOOK.TITLE, "Building your REST API with Spring")
+ .where(BOOK.ID.equal(3)).execute();
+
+ dsl.insertInto(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 3)
+ .set(AUTHOR_BOOK.BOOK_ID, 3)
+ .execute();
+
+ final Result> result = dsl.select(AUTHOR.ID, AUTHOR.LAST_NAME, BOOK.TITLE)
+ .from(AUTHOR)
+ .join(AUTHOR_BOOK).on(AUTHOR.ID.equal(AUTHOR_BOOK.AUTHOR_ID))
+ .join(BOOK).on(AUTHOR_BOOK.BOOK_ID.equal(BOOK.ID))
+ .where(AUTHOR.ID.equal(3))
.fetch();
assertEquals(1, result.size());
- assertEquals(Integer.valueOf(3), result.getValue(0, author.ID));
- assertEquals("Baeldung", result.getValue(0, author.LAST_NAME));
- assertEquals("Building your REST API with Spring", result.getValue(0, book.TITLE));
+ assertEquals(Integer.valueOf(3), result.getValue(0, AUTHOR.ID));
+ assertEquals("Baeldung", result.getValue(0, AUTHOR.LAST_NAME));
+ assertEquals("Building your REST API with Spring", result.getValue(0, BOOK.TITLE));
}
@Test(expected = DataAccessException.class)
public void givenInvalidData_whenUpdating_thenFail() {
- dsl.update(authorBook).set(authorBook.AUTHOR_ID, 4).set(authorBook.BOOK_ID, 5).execute();
+ dsl.update(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 4)
+ .set(AUTHOR_BOOK.BOOK_ID, 5)
+ .execute();
}
@Test
public void givenValidData_whenDeleting_thenSucceed() {
- dsl.delete(author).where(author.ID.lt(3)).execute();
- Result> result = dsl.select(author.ID, author.FIRST_NAME, author.LAST_NAME).from(author).fetch();
+ dsl.delete(AUTHOR)
+ .where(AUTHOR.ID.lt(3))
+ .execute();
+
+ final Result> result = dsl.select(AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
+ .from(AUTHOR)
+ .fetch();
assertEquals(1, result.size());
- assertEquals("Bryan", result.getValue(0, author.FIRST_NAME));
- assertEquals("Basham", result.getValue(0, author.LAST_NAME));
+ assertEquals("Bryan", result.getValue(0, AUTHOR.FIRST_NAME));
+ assertEquals("Basham", result.getValue(0, AUTHOR.LAST_NAME));
}
@Test(expected = DataAccessException.class)
public void givenInvalidData_whenDeleting_thenFail() {
- dsl.delete(book).where(book.ID.equal(1)).execute();
+ dsl.delete(BOOK)
+ .where(BOOK.ID.equal(1))
+ .execute();
}
}
\ No newline at end of file
diff --git a/jooq-spring/src/test/java/com/baeldung/jooq/springboot/Application.java b/jooq-spring/src/test/java/com/baeldung/jooq/springboot/Application.java
new file mode 100644
index 0000000000..ff74851d2a
--- /dev/null
+++ b/jooq-spring/src/test/java/com/baeldung/jooq/springboot/Application.java
@@ -0,0 +1,9 @@
+package com.baeldung.jooq.springboot;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication
+@EnableTransactionManagement
+public class Application {
+}
\ No newline at end of file
diff --git a/jooq-spring/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java b/jooq-spring/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java
new file mode 100644
index 0000000000..c0d9dac797
--- /dev/null
+++ b/jooq-spring/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java
@@ -0,0 +1,39 @@
+package com.baeldung.jooq.springboot;
+
+import com.baeldung.jooq.introduction.ExceptionTranslator;
+import org.jooq.impl.DataSourceConnectionProvider;
+import org.jooq.impl.DefaultConfiguration;
+import org.jooq.impl.DefaultDSLContext;
+import org.jooq.impl.DefaultExecuteListenerProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
+
+import javax.sql.DataSource;
+
+@Configuration
+public class InitialConfiguration {
+
+ @Autowired
+ private DataSource dataSource;
+
+ @Bean
+ public DataSourceConnectionProvider connectionProvider() {
+ return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
+ }
+
+ @Bean
+ public DefaultDSLContext dsl() {
+ return new DefaultDSLContext(configuration());
+ }
+
+ public DefaultConfiguration configuration() {
+ DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
+
+ jooqConfiguration.set(connectionProvider());
+ jooqConfiguration.set(new DefaultExecuteListenerProvider(new ExceptionTranslator()));
+
+ return jooqConfiguration;
+ }
+}
diff --git a/jooq-spring/src/test/java/com/baeldung/jooq/springboot/SpringBootTest.java b/jooq-spring/src/test/java/com/baeldung/jooq/springboot/SpringBootTest.java
new file mode 100644
index 0000000000..f9427f30fb
--- /dev/null
+++ b/jooq-spring/src/test/java/com/baeldung/jooq/springboot/SpringBootTest.java
@@ -0,0 +1,124 @@
+package com.baeldung.jooq.springboot;
+
+import org.jooq.DSLContext;
+import org.jooq.Record3;
+import org.jooq.Result;
+import org.jooq.impl.DSL;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.dao.DataAccessException;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+import static com.baeldung.jooq.introduction.db.public_.tables.Author.AUTHOR;
+import static com.baeldung.jooq.introduction.db.public_.tables.AuthorBook.AUTHOR_BOOK;
+import static com.baeldung.jooq.introduction.db.public_.tables.Book.BOOK;
+import static org.junit.Assert.assertEquals;
+
+@SpringApplicationConfiguration(Application.class)
+@Transactional("transactionManager")
+@RunWith(SpringJUnit4ClassRunner.class)
+public class SpringBootTest {
+
+ @Autowired
+ private DSLContext dsl;
+
+ @Test
+ public void givenValidData_whenInserting_thenSucceed() {
+ dsl.insertInto(AUTHOR)
+ .set(AUTHOR.ID, 4)
+ .set(AUTHOR.FIRST_NAME, "Herbert")
+ .set(AUTHOR.LAST_NAME, "Schildt")
+ .execute();
+
+ dsl.insertInto(BOOK)
+ .set(BOOK.ID, 4)
+ .set(BOOK.TITLE, "A Beginner's Guide")
+ .execute();
+
+ dsl.insertInto(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 4)
+ .set(AUTHOR_BOOK.BOOK_ID, 4)
+ .execute();
+
+ final Result> result = dsl.select(AUTHOR.ID, AUTHOR.LAST_NAME, DSL.count())
+ .from(AUTHOR).join(AUTHOR_BOOK).on(AUTHOR.ID.equal(AUTHOR_BOOK.AUTHOR_ID))
+ .join(BOOK).on(AUTHOR_BOOK.BOOK_ID.equal(BOOK.ID))
+ .groupBy(AUTHOR.LAST_NAME)
+ .fetch();
+
+ assertEquals(3, result.size());
+ assertEquals("Sierra", result.getValue(0, AUTHOR.LAST_NAME));
+ assertEquals(Integer.valueOf(2), result.getValue(0, DSL.count()));
+ assertEquals("Schildt", result.getValue(2, AUTHOR.LAST_NAME));
+ assertEquals(Integer.valueOf(1), result.getValue(2, DSL.count()));
+ }
+
+ @Test(expected = DataAccessException.class)
+ public void givenInvalidData_whenInserting_thenFail() {
+ dsl.insertInto(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 4)
+ .set(AUTHOR_BOOK.BOOK_ID, 5)
+ .execute();
+ }
+
+ @Test
+ public void givenValidData_whenUpdating_thenSucceed() {
+ dsl.update(AUTHOR)
+ .set(AUTHOR.LAST_NAME, "Baeldung")
+ .where(AUTHOR.ID.equal(3))
+ .execute();
+
+ dsl.update(BOOK)
+ .set(BOOK.TITLE, "Building your REST API with Spring")
+ .where(BOOK.ID.equal(3))
+ .execute();
+
+ dsl.insertInto(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 3)
+ .set(AUTHOR_BOOK.BOOK_ID, 3)
+ .execute();
+
+ final Result> result = dsl.select(AUTHOR.ID, AUTHOR.LAST_NAME, BOOK.TITLE)
+ .from(AUTHOR).join(AUTHOR_BOOK).on(AUTHOR.ID.equal(AUTHOR_BOOK.AUTHOR_ID))
+ .join(BOOK).on(AUTHOR_BOOK.BOOK_ID.equal(BOOK.ID))
+ .where(AUTHOR.ID.equal(3))
+ .fetch();
+
+ assertEquals(1, result.size());
+ assertEquals(Integer.valueOf(3), result.getValue(0, AUTHOR.ID));
+ assertEquals("Baeldung", result.getValue(0, AUTHOR.LAST_NAME));
+ assertEquals("Building your REST API with Spring", result.getValue(0, BOOK.TITLE));
+ }
+
+ @Test(expected = DataAccessException.class)
+ public void givenInvalidData_whenUpdating_thenFail() {
+ dsl.update(AUTHOR_BOOK)
+ .set(AUTHOR_BOOK.AUTHOR_ID, 4)
+ .set(AUTHOR_BOOK.BOOK_ID, 5)
+ .execute();
+ }
+
+ @Test
+ public void givenValidData_whenDeleting_thenSucceed() {
+ dsl.delete(AUTHOR)
+ .where(AUTHOR.ID.lt(3))
+ .execute();
+
+ final Result> result = dsl.select(AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
+ .from(AUTHOR).fetch();
+
+ assertEquals(1, result.size());
+ assertEquals("Bryan", result.getValue(0, AUTHOR.FIRST_NAME));
+ assertEquals("Basham", result.getValue(0, AUTHOR.LAST_NAME));
+ }
+
+ @Test(expected = DataAccessException.class)
+ public void givenInvalidData_whenDeleting_thenFail() {
+ dsl.delete(BOOK)
+ .where(BOOK.ID.equal(1))
+ .execute();
+ }
+}
\ No newline at end of file
diff --git a/jsf/pom.xml b/jsf/pom.xml
index 1049bbf38c..c4801996de 100644
--- a/jsf/pom.xml
+++ b/jsf/pom.xml
@@ -90,12 +90,13 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.5.1
+ ${maven-compiler-plugin.version}
1.8
+
org.apache.maven.plugins
maven-war-plugin
@@ -122,6 +123,8 @@
3.1.0
+ 3.5.1
2.6
+
\ No newline at end of file
diff --git a/lombok/pom.xml b/lombok/pom.xml
new file mode 100644
index 0000000000..b816642165
--- /dev/null
+++ b/lombok/pom.xml
@@ -0,0 +1,151 @@
+
+
+
+ 4.0.0
+
+ lombok
+
+ com.baeldung
+ lombok
+ 0.1-SNAPSHOT
+
+
+
+
+ org.projectlombok
+ lombok
+
+ ${lombok.version}
+ provided
+
+
+
+ org.hibernate.javax.persistence
+ hibernate-jpa-2.1-api
+ ${hibernate-jpa-2.1-api.version}
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+
+ ch.qos.logback
+ logback-core
+ ${logback.version}
+ runtime
+
+
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+ lombok
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ ${maven.compiler.target}
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+ org.projectlombok
+ lombok-maven-plugin
+ ${delombok-maven-plugin.version}
+
+
+ delombok
+ generate-sources
+
+ delombok
+
+
+ ${project.basedir}/src/main/java
+ false
+
+ skip
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+ 1.8
+ 1.8
+
+
+ 1.16.8
+
+
+ 1.0.0.Final
+
+
+ 1.7.13
+ 1.1.3
+
+
+ 4.12
+
+
+ 3.5.1
+ 2.19.1
+
+
+ ${lombok.version}.0
+
+
+
diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/ApiClientConfiguration.java b/lombok/src/main/java/com/baeldung/lombok/intro/ApiClientConfiguration.java
new file mode 100644
index 0000000000..74cc929d32
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/intro/ApiClientConfiguration.java
@@ -0,0 +1,22 @@
+package com.baeldung.lombok.intro;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+@Builder
+@Slf4j
+@Getter
+public class ApiClientConfiguration {
+
+ private String host;
+ private int port;
+ private boolean useHttps;
+
+ private long connectTimeout;
+ private long readTimeout;
+
+ private String username;
+ private String password;
+
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/ContactInformationSupport.java b/lombok/src/main/java/com/baeldung/lombok/intro/ContactInformationSupport.java
new file mode 100644
index 0000000000..ea9c3d23f5
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/intro/ContactInformationSupport.java
@@ -0,0 +1,17 @@
+package com.baeldung.lombok.intro;
+
+import lombok.Data;
+
+@Data
+public class ContactInformationSupport implements HasContactInformation {
+
+ private String firstName;
+ private String lastName;
+ private String phoneNr;
+
+ @Override
+ public String getFullName() {
+ return getFirstName() + " " + getLastName();
+ }
+
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/HasContactInformation.java b/lombok/src/main/java/com/baeldung/lombok/intro/HasContactInformation.java
new file mode 100644
index 0000000000..9128df5fb0
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/intro/HasContactInformation.java
@@ -0,0 +1,16 @@
+package com.baeldung.lombok.intro;
+
+public interface HasContactInformation {
+
+ String getFirstName();
+ void setFirstName(String firstName);
+
+ String getFullName();
+
+ String getLastName();
+ void setLastName(String lastName);
+
+ String getPhoneNr();
+ void setPhoneNr(String phoneNr);
+
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/LoginResult.java b/lombok/src/main/java/com/baeldung/lombok/intro/LoginResult.java
new file mode 100644
index 0000000000..6e75696612
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/intro/LoginResult.java
@@ -0,0 +1,25 @@
+package com.baeldung.lombok.intro;
+
+import java.net.URL;
+import java.time.Duration;
+import java.time.Instant;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.Accessors;
+
+@RequiredArgsConstructor
+@Accessors(fluent = true) @Getter
+@EqualsAndHashCode(of = {"authToken"})
+public class LoginResult {
+
+ private final @NonNull Instant loginTs;
+
+ private final @NonNull String authToken;
+ private final @NonNull Duration tokenValidity;
+
+ private final @NonNull URL tokenRefreshUrl;
+
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/User.java b/lombok/src/main/java/com/baeldung/lombok/intro/User.java
new file mode 100644
index 0000000000..d032d1f9e7
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/intro/User.java
@@ -0,0 +1,43 @@
+package com.baeldung.lombok.intro;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Delegate;
+
+@Entity
+@Getter @Setter @NoArgsConstructor // <--- THIS is it
+@ToString(exclude = {"events"})
+public class User implements Serializable, HasContactInformation {
+
+ private @Id @Setter(AccessLevel.PROTECTED) Long id; // will be set when persisting
+
+ private String nickname;
+
+ // Whichever other User-specific attributes
+
+ @Delegate(types = {HasContactInformation.class})
+ private final ContactInformationSupport contactInformation = new ContactInformationSupport();
+
+ // User itelf will implement all contact information by delegation
+
+ @OneToMany(mappedBy = "user")
+ private List events;
+
+ public User(String nickname, String firstName, String lastName, String phoneNr) {
+ this.nickname = nickname;
+ contactInformation.setFirstName(firstName);
+ contactInformation.setLastName(lastName);
+ contactInformation.setPhoneNr(phoneNr);
+ }
+
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/UserEvent.java b/lombok/src/main/java/com/baeldung/lombok/intro/UserEvent.java
new file mode 100644
index 0000000000..6a13608664
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/intro/UserEvent.java
@@ -0,0 +1,29 @@
+package com.baeldung.lombok.intro;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Entity
+@NoArgsConstructor @Getter @Setter
+public class UserEvent implements Serializable {
+
+ // This class is just for sample purposes.
+
+ private @Id @Setter(AccessLevel.PROTECTED) Long id;
+
+ @ManyToOne
+ private User user;
+
+ public UserEvent(User user) {
+ this.user = user;
+ }
+
+}
diff --git a/lombok/src/test/java/com/baeldung/lombok/intro/ApiClientConfigurationTest.java b/lombok/src/test/java/com/baeldung/lombok/intro/ApiClientConfigurationTest.java
new file mode 100644
index 0000000000..8283fc655e
--- /dev/null
+++ b/lombok/src/test/java/com/baeldung/lombok/intro/ApiClientConfigurationTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.lombok.intro;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import com.baeldung.lombok.intro.ApiClientConfiguration.ApiClientConfigurationBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ApiClientConfigurationTest {
+
+ @Test
+ public void givenAnnotatedConfiguration_thenCanBeBuiltViaBuilder() {
+ ApiClientConfiguration config =
+ new ApiClientConfigurationBuilder()
+ .host("api.server.com")
+ .port(443)
+ .useHttps(true)
+ .connectTimeout(15_000L)
+ .readTimeout(5_000L)
+ .username("myusername")
+ .password("secret")
+ .build();
+
+ Assert.assertEquals(config.getHost(), "api.server.com");
+ Assert.assertEquals(config.getPort(), 443);
+ Assert.assertEquals(config.isUseHttps(), true);
+ Assert.assertEquals(config.getConnectTimeout(), 15_000L);
+ Assert.assertEquals(config.getReadTimeout(), 5_000L);
+ Assert.assertEquals(config.getUsername(), "myusername");
+ Assert.assertEquals(config.getPassword(), "secret");
+ }
+
+ @Test
+ public void givenAnnotatedConfiguration_thenHasLoggerInstance() throws NoSuchFieldException {
+ Field loggerInstance = ApiClientConfiguration.class.getDeclaredField("log");
+ int modifiers = loggerInstance.getModifiers();
+ Assert.assertTrue(Modifier.isPrivate(modifiers));
+ Assert.assertTrue(Modifier.isStatic(modifiers));
+ Assert.assertTrue(Modifier.isFinal(modifiers));
+ }
+
+}
diff --git a/lombok/src/test/java/com/baeldung/lombok/intro/LoginResultTest.java b/lombok/src/test/java/com/baeldung/lombok/intro/LoginResultTest.java
new file mode 100644
index 0000000000..56878e4a03
--- /dev/null
+++ b/lombok/src/test/java/com/baeldung/lombok/intro/LoginResultTest.java
@@ -0,0 +1,59 @@
+package com.baeldung.lombok.intro;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.time.Duration;
+import java.time.Instant;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LoginResultTest {
+
+ @Test
+ public void givenAnnotatedLoginResult_thenHasConstructorForAllFinalFields()
+ throws MalformedURLException {
+ /* LoginResult loginResult = */ new LoginResult(
+ Instant.now(),
+ "apitoken",
+ Duration.ofHours(1),
+ new URL("https://api.product.com/token-refresh"));
+ }
+
+ @Test
+ public void givenAnnotatedLoginResult_thenHasFluentGetters()
+ throws MalformedURLException {
+ Instant loginTs = Instant.now();
+ LoginResult loginResult = new LoginResult(
+ loginTs,
+ "apitoken",
+ Duration.ofHours(1),
+ new URL("https://api.product.com/token-refresh"));
+
+ Assert.assertEquals(loginResult.loginTs(), loginTs);
+ Assert.assertEquals(loginResult.authToken(), "apitoken");
+ Assert.assertEquals(loginResult.tokenValidity(), Duration.ofHours(1));
+ Assert.assertEquals(loginResult.tokenRefreshUrl(), new URL("https://api.product.com/token-refresh"));
+ }
+
+ @Test
+ public void givenAnnotatedLoginResult_whenSameApiToken_thenEqualInstances()
+ throws MalformedURLException {
+ String theSameApiToken = "testapitoken";
+
+ LoginResult loginResult1 = new LoginResult(
+ Instant.now(),
+ theSameApiToken,
+ Duration.ofHours(1),
+ new URL("https://api.product.com/token-refresh"));
+
+ LoginResult loginResult2 = new LoginResult(
+ Instant.now(),
+ theSameApiToken,
+ Duration.ofHours(2),
+ new URL("https://api.product.com/token-refresh-alt"));
+
+ Assert.assertEquals(loginResult1, loginResult2);
+ }
+
+}
diff --git a/lombok/src/test/java/com/baeldung/lombok/intro/UserTest.java b/lombok/src/test/java/com/baeldung/lombok/intro/UserTest.java
new file mode 100644
index 0000000000..b3bf21478f
--- /dev/null
+++ b/lombok/src/test/java/com/baeldung/lombok/intro/UserTest.java
@@ -0,0 +1,73 @@
+package com.baeldung.lombok.intro;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UserTest {
+
+ @Test
+ public void givenAnnotatedUser_thenHasEmptyConstructor() {
+ /* User user = */ new User();
+ }
+
+ @Test
+ public void givenAnnotatedUser_thenHasGettersAndSetters() {
+ User user = new User("testnickname", "Test", "JUnit", "123456");
+
+ Assert.assertEquals("testnickname", user.getNickname());
+ Assert.assertEquals("Test", user.getFirstName());
+ Assert.assertEquals("JUnit", user.getLastName());
+ Assert.assertEquals("123456", user.getPhoneNr());
+
+ user.setNickname("testnickname2");
+ user.setFirstName("Test2");
+ user.setLastName("JUnit2");
+ user.setPhoneNr("654321");
+
+ Assert.assertEquals("testnickname2", user.getNickname());
+ Assert.assertEquals("Test2", user.getFirstName());
+ Assert.assertEquals("JUnit2", user.getLastName());
+ Assert.assertEquals("654321", user.getPhoneNr());
+ }
+
+ @Test
+ public void givenAnnotatedUser_thenHasProtectedSetId() throws NoSuchMethodException {
+ Method setIdMethod = User.class.getDeclaredMethod("setId", Long.class);
+ int modifiers = setIdMethod.getModifiers();
+ Assert.assertTrue(Modifier.isProtected(modifiers));
+ }
+
+ @Test
+ public void givenAnnotatedUser_thenImplementsHasContactInformation() {
+ User user = new User("testnickname3", "Test3", "JUnit3", "987654");
+ Assert.assertTrue(user instanceof HasContactInformation);
+
+ Assert.assertEquals("Test3", user.getFirstName());
+ Assert.assertEquals("JUnit3", user.getLastName());
+ Assert.assertEquals("987654", user.getPhoneNr());
+ Assert.assertEquals("Test3 JUnit3", user.getFullName());
+
+ user.setFirstName("Test4");
+ user.setLastName("JUnit4");
+ user.setPhoneNr("456789");
+
+ Assert.assertEquals("Test4", user.getFirstName());
+ Assert.assertEquals("JUnit4", user.getLastName());
+ Assert.assertEquals("456789", user.getPhoneNr());
+ Assert.assertEquals("Test4 JUnit4", user.getFullName());
+ }
+
+ @Test
+ public void givenAnnotatedUser_whenHasEvents_thenToStringDumpsNoEvents() {
+ User user = new User("testnickname", "Test", "JUnit", "123456");
+ List events = Arrays.asList(new UserEvent(user), new UserEvent(user));
+ user.setEvents(events);
+ Assert.assertFalse(user.toString().contains("events"));
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index d6a1d7c034..85861685ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,8 +20,10 @@
httpclient
jackson
javaxval
+ jooq-spring
json-path
mockito
+ jee7schedule
querydsl
@@ -65,7 +67,9 @@
spring-thymeleaf
spring-zuul
jsf
+ xml
+ lombok
diff --git a/rest-testing/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/rest-testing/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
deleted file mode 100644
index 627021fb96..0000000000
--- a/rest-testing/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/rest-testing/.gitignore b/rest-testing/.gitignore
index 83c05e60c8..601d2281e5 100644
--- a/rest-testing/.gitignore
+++ b/rest-testing/.gitignore
@@ -10,4 +10,8 @@
# Packaged files #
*.jar
*.war
-*.ear
\ No newline at end of file
+*.ear
+
+.externalToolBuilders
+.settings
+.springBeans
\ No newline at end of file
diff --git a/rest-testing/.project b/rest-testing/.project
deleted file mode 100644
index 1dc9ce93fe..0000000000
--- a/rest-testing/.project
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
- rest-testing
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.jem.workbench.JavaEMFNature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
- org.eclipse.m2e.core.maven2Nature
- org.eclipse.wst.common.project.facet.core.nature
-
-
diff --git a/rest-testing/.settings/.jsdtscope b/rest-testing/.settings/.jsdtscope
deleted file mode 100644
index 7b3f0c8b9f..0000000000
--- a/rest-testing/.settings/.jsdtscope
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/rest-testing/.settings/org.eclipse.jdt.core.prefs b/rest-testing/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index b126d6476b..0000000000
--- a/rest-testing/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,95 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=error
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/rest-testing/.settings/org.eclipse.jdt.ui.prefs b/rest-testing/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 471e9b0d81..0000000000
--- a/rest-testing/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,55 +0,0 @@
-#Sat Jan 21 23:04:06 EET 2012
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=true
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=true
-sp_cleanup.correct_indentation=true
-sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=true
-sp_cleanup.make_local_variable_final=true
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=false
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=false
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=true
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=true
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=false
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=true
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=true
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/rest-testing/.settings/org.eclipse.m2e.core.prefs b/rest-testing/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f1cb..0000000000
--- a/rest-testing/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/rest-testing/.settings/org.eclipse.m2e.wtp.prefs b/rest-testing/.settings/org.eclipse.m2e.wtp.prefs
deleted file mode 100644
index ef86089622..0000000000
--- a/rest-testing/.settings/org.eclipse.m2e.wtp.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false
diff --git a/rest-testing/.settings/org.eclipse.wst.common.component b/rest-testing/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index e98377cb0f..0000000000
--- a/rest-testing/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/rest-testing/.settings/org.eclipse.wst.common.project.facet.core.xml b/rest-testing/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index f4ef8aa0a5..0000000000
--- a/rest-testing/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/rest-testing/.settings/org.eclipse.wst.jsdt.ui.superType.container b/rest-testing/.settings/org.eclipse.wst.jsdt.ui.superType.container
deleted file mode 100644
index 3bd5d0a480..0000000000
--- a/rest-testing/.settings/org.eclipse.wst.jsdt.ui.superType.container
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/rest-testing/.settings/org.eclipse.wst.jsdt.ui.superType.name b/rest-testing/.settings/org.eclipse.wst.jsdt.ui.superType.name
deleted file mode 100644
index 05bd71b6ec..0000000000
--- a/rest-testing/.settings/org.eclipse.wst.jsdt.ui.superType.name
+++ /dev/null
@@ -1 +0,0 @@
-Window
\ No newline at end of file
diff --git a/rest-testing/.settings/org.eclipse.wst.validation.prefs b/rest-testing/.settings/org.eclipse.wst.validation.prefs
deleted file mode 100644
index cacf5451ae..0000000000
--- a/rest-testing/.settings/org.eclipse.wst.validation.prefs
+++ /dev/null
@@ -1,14 +0,0 @@
-DELEGATES_PREFERENCE=delegateValidatorList
-USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.303.v201202090300
-eclipse.preferences.version=1
-override=true
-suspend=false
-vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01
-vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01
-vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02
-vf.version=3
diff --git a/rest-testing/.settings/org.eclipse.wst.ws.service.policy.prefs b/rest-testing/.settings/org.eclipse.wst.ws.service.policy.prefs
deleted file mode 100644
index 9cfcabe16f..0000000000
--- a/rest-testing/.settings/org.eclipse.wst.ws.service.policy.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.wst.ws.service.policy.projectEnabled=false
diff --git a/rest-testing/.springBeans b/rest-testing/.springBeans
deleted file mode 100644
index a79097f40d..0000000000
--- a/rest-testing/.springBeans
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/webapp/WEB-INF/api-servlet.xml
-
-
-
-
diff --git a/rest-testing/pom.xml b/rest-testing/pom.xml
index e159af0b77..652f2ab601 100644
--- a/rest-testing/pom.xml
+++ b/rest-testing/pom.xml
@@ -1,173 +1,191 @@
-
- 4.0.0
- com.baeldung
- rest-testing
- 0.1-SNAPSHOT
+
+ 4.0.0
+ com.baeldung
+ rest-testing
+ 0.1-SNAPSHOT
- rest-testing
+ rest-testing
-
+
-
+
-
- com.google.guava
- guava
- ${guava.version}
-
+
+ com.google.guava
+ guava
+ ${guava.version}
+
-
- commons-io
- commons-io
- 2.4
-
+
+ commons-io
+ commons-io
+ 2.4
+
-
- org.apache.commons
- commons-lang3
- ${commons-lang3.version}
-
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
-
+
-
- org.apache.httpcomponents
- httpclient
- ${httpclient.version}
-
-
- org.apache.httpcomponents
- httpcore
- ${httpcore.version}
-
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+
+
+ org.apache.httpcomponents
+ httpcore
+ ${httpcore.version}
+
-
+
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
-
+
-
- org.slf4j
- slf4j-api
- ${org.slf4j.version}
-
-
- ch.qos.logback
- logback-classic
- ${logback.version}
-
-
-
- org.slf4j
- jcl-over-slf4j
- ${org.slf4j.version}
- runtime
-
-
- org.slf4j
- log4j-over-slf4j
- ${org.slf4j.version}
-
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${org.slf4j.version}
+ runtime
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${org.slf4j.version}
+
-
+
-
- junit
- junit
- ${junit.version}
- test
-
+
+ junit
+ junit
+ ${junit.version}
+ test
+
-
- org.hamcrest
- hamcrest-core
- ${org.hamcrest.version}
- test
-
-
- org.hamcrest
- hamcrest-library
- ${org.hamcrest.version}
- test
-
+
+ org.hamcrest
+ hamcrest-core
+ ${org.hamcrest.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-library
+ ${org.hamcrest.version}
+ test
+
-
- org.mockito
- mockito-core
- ${mockito.version}
- test
-
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+ com.github.tomakehurst
+ wiremock
+ 1.58
+ test
+
-
+
+ info.cukes
+ cucumber-java
+ 1.2.4
+ test
+
+
+ info.cukes
+ cucumber-junit
+ 1.2.4
+
+
-
- rest-testing
-
-
- src/main/resources
- true
-
-
+
+ rest-testing
+
+
+ src/main/resources
+ true
+
+
-
+
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
-
- 1.8
-
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ 1.8
+
+
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
-
+
-
+
-
-
- 2.7.2
+
+
+ 2.7.2
-
- 1.7.13
- 1.1.3
+
+ 1.7.13
+ 1.1.3
-
- 5.1.3.Final
+
+ 5.1.3.Final
-
- 19.0
- 3.4
+
+ 19.0
+ 3.4
-
- 1.3
- 4.12
- 1.10.19
+
+ 1.3
+ 4.12
+ 1.10.19
- 4.4.1
- 4.5
+ 4.4.1
+ 4.5
- 2.9.0
+ 2.9.0
-
- 3.5.1
- 2.6
- 2.19.1
- 2.7
- 1.4.18
+
+ 3.5.1
+ 2.6
+ 2.19.1
+ 2.7
+ 1.4.18
-
+
\ No newline at end of file
diff --git a/rest-testing/src/main/resources/Feature/cucumber.feature b/rest-testing/src/main/resources/Feature/cucumber.feature
new file mode 100644
index 0000000000..99dd8249fe
--- /dev/null
+++ b/rest-testing/src/main/resources/Feature/cucumber.feature
@@ -0,0 +1,10 @@
+Feature: Testing a REST API
+ Users should be able to submit GET and POST requests to a web service, represented by WireMock
+
+ Scenario: Data Upload to a web service
+ When users upload data on a project
+ Then the server should handle it and return a success status
+
+ Scenario: Data retrieval from a web service
+ When users want to get information on the Cucumber project
+ Then the requested data is returned
\ No newline at end of file
diff --git a/rest-testing/src/main/resources/cucumber.json b/rest-testing/src/main/resources/cucumber.json
new file mode 100644
index 0000000000..38ebe066ac
--- /dev/null
+++ b/rest-testing/src/main/resources/cucumber.json
@@ -0,0 +1,14 @@
+{
+ "testing-framework": "cucumber",
+ "supported-language":
+ [
+ "Ruby",
+ "Java",
+ "Javascript",
+ "PHP",
+ "Python",
+ "C++"
+ ],
+
+ "website": "cucumber.io"
+}
\ No newline at end of file
diff --git a/rest-testing/src/main/resources/wiremock_intro.json b/rest-testing/src/main/resources/wiremock_intro.json
new file mode 100644
index 0000000000..ece2d35907
--- /dev/null
+++ b/rest-testing/src/main/resources/wiremock_intro.json
@@ -0,0 +1,5 @@
+{
+ "testing-library": "WireMock",
+ "creator": "Tom Akehurst",
+ "website": "wiremock.org"
+}
\ No newline at end of file
diff --git a/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberTest.java b/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberTest.java
new file mode 100644
index 0000000000..041de592e9
--- /dev/null
+++ b/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberTest.java
@@ -0,0 +1,10 @@
+package com.baeldung.rest.cucumber;
+
+import org.junit.runner.RunWith;
+import cucumber.api.CucumberOptions;
+import cucumber.api.junit.Cucumber;
+
+@RunWith(Cucumber.class)
+@CucumberOptions(features = "classpath:Feature")
+public class CucumberTest {
+}
\ No newline at end of file
diff --git a/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java b/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java
new file mode 100644
index 0000000000..b461da8403
--- /dev/null
+++ b/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java
@@ -0,0 +1,101 @@
+package com.baeldung.rest.cucumber;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import cucumber.api.java.en.Then;
+import cucumber.api.java.en.When;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+public class StepDefinition {
+
+ private static final String CREATE_PATH = "/create";
+ private static final String APPLICATION_JSON = "application/json";
+
+ private final InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("cucumber.json");
+ private final String jsonString = new Scanner(jsonInputStream, "UTF-8").useDelimiter("\\Z").next();
+
+ private final WireMockServer wireMockServer = new WireMockServer();
+ private final CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ @When("^users upload data on a project$")
+ public void usersUploadDataOnAProject() throws IOException {
+ wireMockServer.start();
+
+ configureFor("localhost", 8080);
+ stubFor(post(urlEqualTo(CREATE_PATH))
+ .withHeader("content-type", equalTo(APPLICATION_JSON))
+ .withRequestBody(containing("testing-framework"))
+ .willReturn(aResponse().withStatus(200)));
+
+ HttpPost request = new HttpPost("http://localhost:8080/create");
+ StringEntity entity = new StringEntity(jsonString);
+ request.addHeader("content-type", APPLICATION_JSON);
+ request.setEntity(entity);
+ HttpResponse response = httpClient.execute(request);
+
+ assertEquals(200, response.getStatusLine().getStatusCode());
+ verify(postRequestedFor(urlEqualTo(CREATE_PATH))
+ .withHeader("content-type", equalTo(APPLICATION_JSON)));
+
+ wireMockServer.stop();
+ }
+
+ @When("^users want to get information on the (.+) project$")
+ public void usersGetInformationOnAProject(String projectName) throws IOException {
+ wireMockServer.start();
+
+ configureFor("localhost", 8080);
+ stubFor(get(urlEqualTo("/projects/cucumber")).withHeader("accept", equalTo(APPLICATION_JSON))
+ .willReturn(aResponse().withBody(jsonString)));
+
+ HttpGet request = new HttpGet("http://localhost:8080/projects/" + projectName.toLowerCase());
+ request.addHeader("accept", APPLICATION_JSON);
+ HttpResponse httpResponse = httpClient.execute(request);
+ String responseString = convertResponseToString(httpResponse);
+
+ assertThat(responseString, containsString("\"testing-framework\": \"cucumber\""));
+ assertThat(responseString, containsString("\"website\": \"cucumber.io\""));
+ verify(getRequestedFor(urlEqualTo("/projects/cucumber")).withHeader("accept", equalTo(APPLICATION_JSON)));
+
+ wireMockServer.stop();
+ }
+
+ @Then("^the server should handle it and return a success status$")
+ public void theServerShouldReturnASuccessStatus() {
+ }
+
+ @Then("^the requested data is returned$")
+ public void theRequestedDataIsReturned() {
+ }
+
+ private String convertResponseToString(HttpResponse response) throws IOException {
+ InputStream responseStream = response.getEntity().getContent();
+ Scanner scanner = new Scanner(responseStream, "UTF-8");
+ String responseString = scanner.useDelimiter("\\Z").next();
+ scanner.close();
+ return responseString;
+ }
+}
\ No newline at end of file
diff --git a/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManaged.java b/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManaged.java
new file mode 100644
index 0000000000..664c3fac78
--- /dev/null
+++ b/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManaged.java
@@ -0,0 +1,144 @@
+package com.baeldung.rest.wiremock.introduction;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.matching;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+import static org.junit.Assert.assertEquals;
+
+public class JUnitManaged {
+
+ private static final String BAELDUNG_WIREMOCK_PATH = "/baeldung/wiremock";
+ private static final String APPLICATION_JSON = "application/json";
+
+ @Rule
+ public WireMockRule wireMockRule = new WireMockRule();
+
+ @Test
+ public void givenJUnitManagedServer_whenMatchingURL_thenCorrect() throws IOException {
+ stubFor(get(urlPathMatching("/baeldung/.*"))
+ .willReturn(aResponse()
+ .withStatus(200)
+ .withHeader("Content-Type", APPLICATION_JSON)
+ .withBody("\"testing-library\": \"WireMock\"")));
+
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock");
+ HttpResponse httpResponse = httpClient.execute(request);
+ String stringResponse = convertHttpResponseToString(httpResponse);
+
+ verify(getRequestedFor(urlEqualTo(BAELDUNG_WIREMOCK_PATH)));
+ assertEquals(200, httpResponse.getStatusLine().getStatusCode());
+ assertEquals(APPLICATION_JSON, httpResponse.getFirstHeader("Content-Type").getValue());
+ assertEquals("\"testing-library\": \"WireMock\"", stringResponse);
+ }
+
+ @Test
+ public void givenJUnitManagedServer_whenMatchingHeaders_thenCorrect() throws IOException {
+ stubFor(get(urlPathEqualTo(BAELDUNG_WIREMOCK_PATH))
+ .withHeader("Accept", matching("text/.*"))
+ .willReturn(aResponse()
+ .withStatus(503)
+ .withHeader("Content-Type", "text/html")
+ .withBody("!!! Service Unavailable !!!")));
+
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock");
+ request.addHeader("Accept", "text/html");
+ HttpResponse httpResponse = httpClient.execute(request);
+ String stringResponse = convertHttpResponseToString(httpResponse);
+
+ verify(getRequestedFor(urlEqualTo(BAELDUNG_WIREMOCK_PATH)));
+ assertEquals(503, httpResponse.getStatusLine().getStatusCode());
+ assertEquals("text/html", httpResponse.getFirstHeader("Content-Type").getValue());
+ assertEquals("!!! Service Unavailable !!!", stringResponse);
+ }
+
+ @Test
+ public void givenJUnitManagedServer_whenMatchingBody_thenCorrect() throws IOException {
+ stubFor(post(urlEqualTo(BAELDUNG_WIREMOCK_PATH))
+ .withHeader("Content-Type", equalTo(APPLICATION_JSON))
+ .withRequestBody(containing("\"testing-library\": \"WireMock\""))
+ .withRequestBody(containing("\"creator\": \"Tom Akehurst\""))
+ .withRequestBody(containing("\"website\": \"wiremock.org\""))
+ .willReturn(aResponse().withStatus(200)));
+
+ InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("wiremock_intro.json");
+ String jsonString = convertInputStreamToString(jsonInputStream);
+ StringEntity entity = new StringEntity(jsonString);
+
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpPost request = new HttpPost("http://localhost:8080/baeldung/wiremock");
+ request.addHeader("Content-Type", APPLICATION_JSON);
+ request.setEntity(entity);
+ HttpResponse response = httpClient.execute(request);
+
+ verify(postRequestedFor(urlEqualTo(BAELDUNG_WIREMOCK_PATH))
+ .withHeader("Content-Type", equalTo(APPLICATION_JSON)));
+ assertEquals(200, response.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void givenJUnitManagedServer_whenNotUsingPriority_thenCorrect() throws IOException {
+ stubFor(get(urlPathMatching("/baeldung/.*")).willReturn(aResponse().withStatus(200)));
+ stubFor(get(urlPathEqualTo(BAELDUNG_WIREMOCK_PATH)).withHeader("Accept", matching("text/.*")).willReturn(aResponse().withStatus(503)));
+
+ HttpResponse httpResponse = generateClientAndReceiveResponseForPriorityTests();
+
+ verify(getRequestedFor(urlEqualTo(BAELDUNG_WIREMOCK_PATH)));
+ assertEquals(503, httpResponse.getStatusLine().getStatusCode());
+ }
+
+ @Test
+ public void givenJUnitManagedServer_whenUsingPriority_thenCorrect() throws IOException {
+ stubFor(get(urlPathMatching("/baeldung/.*")).atPriority(1).willReturn(aResponse().withStatus(200)));
+ stubFor(get(urlPathEqualTo(BAELDUNG_WIREMOCK_PATH)).atPriority(2).withHeader("Accept", matching("text/.*")).willReturn(aResponse().withStatus(503)));
+
+ HttpResponse httpResponse = generateClientAndReceiveResponseForPriorityTests();
+
+ verify(getRequestedFor(urlEqualTo(BAELDUNG_WIREMOCK_PATH)));
+ assertEquals(200, httpResponse.getStatusLine().getStatusCode());
+ }
+
+ private static String convertHttpResponseToString(HttpResponse httpResponse) throws IOException {
+ InputStream inputStream = httpResponse.getEntity().getContent();
+ return convertInputStreamToString(inputStream);
+ }
+
+ private static String convertInputStreamToString(InputStream inputStream) {
+ Scanner scanner = new Scanner(inputStream, "UTF-8");
+ String string = scanner.useDelimiter("\\Z").next();
+ scanner.close();
+ return string;
+ }
+
+ private HttpResponse generateClientAndReceiveResponseForPriorityTests() throws IOException {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock");
+ request.addHeader("Accept", "text/xml");
+ return httpClient.execute(request);
+ }
+}
\ No newline at end of file
diff --git a/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManaged.java b/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManaged.java
new file mode 100644
index 0000000000..ad7caa52b5
--- /dev/null
+++ b/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManaged.java
@@ -0,0 +1,54 @@
+package com.baeldung.rest.wiremock.introduction;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+import static org.junit.Assert.assertEquals;
+
+public class ProgrammaticallyManaged {
+
+ private static final String BAELDUNG_PATH = "/baeldung";
+
+ private WireMockServer wireMockServer = new WireMockServer();
+ private CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ @Test
+ public void givenProgrammaticallyManagedServer_whenUsingSimpleStubbing_thenCorrect() throws IOException {
+ wireMockServer.start();
+
+ configureFor("localhost", 8080);
+ stubFor(get(urlEqualTo(BAELDUNG_PATH)).willReturn(aResponse().withBody("Welcome to Baeldung!")));
+
+ HttpGet request = new HttpGet("http://localhost:8080/baeldung");
+ HttpResponse httpResponse = httpClient.execute(request);
+ String stringResponse = convertResponseToString(httpResponse);
+
+ verify(getRequestedFor(urlEqualTo(BAELDUNG_PATH)));
+ assertEquals("Welcome to Baeldung!", stringResponse);
+
+ wireMockServer.stop();
+ }
+
+ private static String convertResponseToString(HttpResponse response) throws IOException {
+ InputStream responseStream = response.getEntity().getContent();
+ Scanner scanner = new Scanner(responseStream, "UTF-8");
+ String stringResponse = scanner.useDelimiter("\\Z").next();
+ scanner.close();
+ return stringResponse;
+ }
+}
\ No newline at end of file
diff --git a/rest-testing/src/test/resources/.gitignore b/rest-testing/src/test/resources/.gitignore
deleted file mode 100644
index 83c05e60c8..0000000000
--- a/rest-testing/src/test/resources/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-*.class
-
-#folders#
-/target
-/neoDb*
-/data
-/src/main/webapp/WEB-INF/classes
-*/META-INF/*
-
-# Packaged files #
-*.jar
-*.war
-*.ear
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java b/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java
new file mode 100644
index 0000000000..ae1c6157db
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java
@@ -0,0 +1,15 @@
+package org.baeldung.scopes;
+
+public class HelloMessageGenerator {
+
+ private String message;
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(final String message) {
+ this.message = message;
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/scopes/Person.java b/spring-all/src/main/java/org/baeldung/scopes/Person.java
new file mode 100644
index 0000000000..e6139c31dd
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/scopes/Person.java
@@ -0,0 +1,27 @@
+package org.baeldung.scopes;
+
+public class Person {
+ private String name;
+ private int age;
+
+ public Person() {
+ }
+
+ public Person(final String name, final int age) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "Person [name=" + name + "]";
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java
new file mode 100644
index 0000000000..bf733b75f9
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java
@@ -0,0 +1,31 @@
+package org.baeldung.scopes;
+
+import javax.annotation.Resource;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class ScopesController {
+ public static final Logger LOG = Logger.getLogger(ScopesController.class);
+
+ @Resource(name = "requestMessage")
+ HelloMessageGenerator requestMessage;
+
+ @Resource(name = "sessionMessage")
+ HelloMessageGenerator sessionMessage;
+
+ @RequestMapping("/scopes")
+ public String getScopes(final Model model) {
+ LOG.info("Request Message:" + requestMessage.getMessage());
+ LOG.info("Session Message" + sessionMessage.getMessage());
+ requestMessage.setMessage("Good morning!");
+ sessionMessage.setMessage("Good afternoon!");
+ model.addAttribute("requestMessage", requestMessage.getMessage());
+ model.addAttribute("sessionMessage", sessionMessage.getMessage());
+ return "scopesExample";
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java
new file mode 100644
index 0000000000..5a9b266388
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java
@@ -0,0 +1,57 @@
+package org.baeldung.spring.config;
+
+import org.baeldung.scopes.HelloMessageGenerator;
+import org.baeldung.scopes.Person;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.view.JstlView;
+import org.springframework.web.servlet.view.UrlBasedViewResolver;
+
+@Configuration
+@ComponentScan("org.baeldung.scopes")
+@EnableWebMvc
+public class ScopesConfig {
+ @Bean
+ public UrlBasedViewResolver setupViewResolver() {
+ final UrlBasedViewResolver resolver = new UrlBasedViewResolver();
+ resolver.setPrefix("/WEB-INF/view/");
+ resolver.setSuffix(".jsp");
+ resolver.setViewClass(JstlView.class);
+ return resolver;
+ }
+
+ @Bean
+ @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public HelloMessageGenerator requestMessage() {
+ return new HelloMessageGenerator();
+ }
+
+ @Bean
+ @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public HelloMessageGenerator sessionMessage() {
+ return new HelloMessageGenerator();
+ }
+
+ @Bean
+ @Scope(value = WebApplicationContext.SCOPE_GLOBAL_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public HelloMessageGenerator globalSessionMessage() {
+ return new HelloMessageGenerator();
+ }
+
+ @Bean
+ @Scope("prototype")
+ public Person personPrototype() {
+ return new Person();
+ }
+
+ @Bean
+ @Scope("singleton")
+ public Person personSingleton() {
+ return new Person();
+ }
+}
diff --git a/spring-all/src/main/resources/scopes.xml b/spring-all/src/main/resources/scopes.xml
new file mode 100644
index 0000000000..faecd727fa
--- /dev/null
+++ b/spring-all/src/main/resources/scopes.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp
new file mode 100644
index 0000000000..7974cf0220
--- /dev/null
+++ b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp
@@ -0,0 +1,10 @@
+
+
+
+
+ Bean Scopes Examples
+
+ Request Message: ${requestMessage }
+ Session Message: ${sessionMessage }
+
+
\ No newline at end of file
diff --git a/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java b/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java
new file mode 100644
index 0000000000..b1dd248c26
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java
@@ -0,0 +1,43 @@
+package org.baeldung.scopes;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class ScopesTest {
+
+ private static final String NAME = "John Smith";
+ private static final String NAME_OTHER = "Anna Jones";
+
+ @Test
+ public void testScopeSingleton() {
+ final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml");
+
+ final Person personSingletonA = (Person) applicationContext.getBean("personSingleton");
+ final Person personSingletonB = (Person) applicationContext.getBean("personSingleton");
+
+ personSingletonA.setName(NAME);
+ Assert.assertEquals(NAME, personSingletonB.getName());
+
+ ((AbstractApplicationContext) applicationContext).close();
+ }
+
+ @Test
+ public void testScopePrototype() {
+ final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml");
+
+ final Person personPrototypeA = (Person) applicationContext.getBean("personPrototype");
+ final Person personPrototypeB = (Person) applicationContext.getBean("personPrototype");
+
+ personPrototypeA.setName(NAME);
+ personPrototypeB.setName(NAME_OTHER);
+
+ Assert.assertEquals(NAME, personPrototypeA.getName());
+ Assert.assertEquals(NAME_OTHER, personPrototypeB.getName());
+
+ ((AbstractApplicationContext) applicationContext).close();
+ }
+
+}
diff --git a/spring-data-couchbase-2/README.md b/spring-data-couchbase-2/README.md
index e58e37e090..3ed226fb33 100644
--- a/spring-data-couchbase-2/README.md
+++ b/spring-data-couchbase-2/README.md
@@ -2,11 +2,12 @@
### Relevant Articles:
- [Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase)
+- [Entity Validation, Query Consistency, and Optimistic Locking in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase)
### Overview
This Maven project contains the Java code for Spring Data Couchbase
entities, repositories, and template-based services
-as described in the tutorial, as well as a unit test
+as described in the tutorials, as well as a unit/integration test
for each service implementation.
### Working with the Code
@@ -22,13 +23,16 @@ mvn clean install
```
### Running the tests
-There are three test classes in src/test/java in the package
+The following test classes are in src/test/java in the package
org.baeldung.spring.data.couchbase.service:
- PersonServiceTest (abstract)
- PersonRepositoryTest (concrete)
- PersonTemplateServiceTest (concrete)
+- StudentServiceTest (abstract)
+- StudentRepositoryTest (concrete)
+- StudentTemplateServiceTest (concrete)
-The latter two may be run as JUnit tests from your IDE
+The concrete test classes may be run as JUnit tests from your IDE
or using the Maven command line:
```
mvn test
diff --git a/spring-data-couchbase-2/pom.xml b/spring-data-couchbase-2/pom.xml
index 93b3dbddb4..d24ef4aeaa 100644
--- a/spring-data-couchbase-2/pom.xml
+++ b/spring-data-couchbase-2/pom.xml
@@ -93,7 +93,7 @@
1.7
UTF-8
4.2.4.RELEASE
- 2.0.0.RELEASE
+ 2.1.1.RELEASE
5.2.4.Final
2.9.2
1.1.3
diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java
index bedae26e00..3fabf7a11e 100644
--- a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java
+++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/PersonServiceTest.java
@@ -27,28 +27,20 @@ public abstract class PersonServiceTest extends IntegrationTest {
static final String smith = "Smith";
static final String johnSmithId = "person:" + john + ":" + smith;
static final Person johnSmith = new Person(johnSmithId, john, smith);
- static final JsonObject jsonJohnSmith = JsonObject.empty()
- .put(typeField, Person.class.getName())
- .put("firstName", john)
- .put("lastName", smith)
- .put("created", DateTime.now().getMillis());
+ static final JsonObject jsonJohnSmith = JsonObject.empty().put(typeField, Person.class.getName()).put("firstName", john).put("lastName", smith).put("created", DateTime.now().getMillis());
static final String foo = "Foo";
static final String bar = "Bar";
static final String foobarId = "person:" + foo + ":" + bar;
static final Person foobar = new Person(foobarId, foo, bar);
- static final JsonObject jsonFooBar = JsonObject.empty()
- .put(typeField, Person.class.getName())
- .put("firstName", foo)
- .put("lastName", bar)
- .put("created", DateTime.now().getMillis());
-
+ static final JsonObject jsonFooBar = JsonObject.empty().put(typeField, Person.class.getName()).put("firstName", foo).put("lastName", bar).put("created", DateTime.now().getMillis());
+
PersonService personService;
-
+
@BeforeClass
public static void setupBeforeClass() {
- Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST);
- Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.BUCKET_PASSWORD);
+ final Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST);
+ final Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.BUCKET_PASSWORD);
bucket.upsert(JsonDocument.create(johnSmithId, jsonJohnSmith));
bucket.upsert(JsonDocument.create(foobarId, jsonFooBar));
bucket.close();
@@ -57,7 +49,7 @@ public abstract class PersonServiceTest extends IntegrationTest {
@Test
public void whenFindingPersonByJohnSmithId_thenReturnsJohnSmith() {
- Person actualPerson = personService.findOne(johnSmithId);
+ final Person actualPerson = personService.findOne(johnSmithId);
assertNotNull(actualPerson);
assertNotNull(actualPerson.getCreated());
assertEquals(johnSmith, actualPerson);
@@ -65,7 +57,7 @@ public abstract class PersonServiceTest extends IntegrationTest {
@Test
public void whenFindingAllPersons_thenReturnsTwoOrMorePersonsIncludingJohnSmithAndFooBar() {
- List resultList = personService.findAll();
+ final List resultList = personService.findAll();
assertNotNull(resultList);
assertFalse(resultList.isEmpty());
assertTrue(resultContains(resultList, johnSmith));
@@ -75,8 +67,8 @@ public abstract class PersonServiceTest extends IntegrationTest {
@Test
public void whenFindingByFirstNameJohn_thenReturnsOnlyPersonsNamedJohn() {
- String expectedFirstName = john;
- List resultList = personService.findByFirstName(expectedFirstName);
+ final String expectedFirstName = john;
+ final List resultList = personService.findByFirstName(expectedFirstName);
assertNotNull(resultList);
assertFalse(resultList.isEmpty());
assertTrue(allResultsContainExpectedFirstName(resultList, expectedFirstName));
@@ -84,17 +76,24 @@ public abstract class PersonServiceTest extends IntegrationTest {
@Test
public void whenFindingByLastNameSmith_thenReturnsOnlyPersonsNamedSmith() {
- String expectedLastName = smith;
- List resultList = personService.findByLastName(expectedLastName);
+ final String expectedLastName = smith;
+ final List resultList = personService.findByLastName(expectedLastName);
assertNotNull(resultList);
assertFalse(resultList.isEmpty());
assertTrue(allResultsContainExpectedLastName(resultList, expectedLastName));
}
-
+
+ @Test
+ public void whenFindingByFirstNameJohn_thenReturnsOnePersonNamedJohn() {
+ final String expectedFirstName = john;
+ final List resultList = personService.findByFirstName(expectedFirstName);
+ assertTrue(resultList.size() == 1);
+ }
+
private boolean resultContains(List resultList, Person person) {
boolean found = false;
- for(Person p : resultList) {
- if(p.equals(person)) {
+ for (final Person p : resultList) {
+ if (p.equals(person)) {
found = true;
break;
}
@@ -104,8 +103,8 @@ public abstract class PersonServiceTest extends IntegrationTest {
private boolean allResultsContainExpectedFirstName(List resultList, String firstName) {
boolean found = false;
- for(Person p : resultList) {
- if(p.getFirstName().equals(firstName)) {
+ for (final Person p : resultList) {
+ if (p.getFirstName().equals(firstName)) {
found = true;
break;
}
@@ -115,8 +114,8 @@ public abstract class PersonServiceTest extends IntegrationTest {
private boolean allResultsContainExpectedLastName(List resultList, String lastName) {
boolean found = false;
- for(Person p : resultList) {
- if(p.getLastName().equals(lastName)) {
+ for (final Person p : resultList) {
+ if (p.getLastName().equals(lastName)) {
found = true;
break;
}
diff --git a/rest-testing/.classpath b/spring-data-couchbase-2b/.classpath
similarity index 94%
rename from rest-testing/.classpath
rename to spring-data-couchbase-2b/.classpath
index 8ebf6d9c31..450036fc00 100644
--- a/rest-testing/.classpath
+++ b/spring-data-couchbase-2b/.classpath
@@ -1,5 +1,10 @@
+
+
+
+
+
@@ -12,12 +17,12 @@
-
+
-
+
@@ -27,10 +32,5 @@
-
-
-
-
-
diff --git a/jooq-spring/.project b/spring-data-couchbase-2b/.project
similarity index 84%
rename from jooq-spring/.project
rename to spring-data-couchbase-2b/.project
index a291146b79..1690ad8ce2 100644
--- a/jooq-spring/.project
+++ b/spring-data-couchbase-2b/.project
@@ -1,7 +1,8 @@
- jooq-spring
-
+ spring-data-couchbase-2
+ This project is a simple template for a jar utility using Spring.
+
diff --git a/spring-data-couchbase-2b/.springBeans b/spring-data-couchbase-2b/.springBeans
new file mode 100644
index 0000000000..0c014a97b6
--- /dev/null
+++ b/spring-data-couchbase-2b/.springBeans
@@ -0,0 +1,20 @@
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+ true
+ false
+
+
+
+
+
diff --git a/spring-data-couchbase-2b/README.md b/spring-data-couchbase-2b/README.md
new file mode 100644
index 0000000000..262962f58a
--- /dev/null
+++ b/spring-data-couchbase-2b/README.md
@@ -0,0 +1,36 @@
+## Spring Data Couchbase Tutorial Project
+
+### Relevant Articles:
+- [Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase)
+- [Entity Validation, Query Consistency, and Optimistic Locking in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase)
+
+### Overview
+This Maven project contains the Java code for Spring Data Couchbase
+entities, repositories, and repository-based services
+as described in the tutorials, as well as a unit/integration test
+for each service implementation.
+
+### Working with the Code
+The project was developed and tested using Java 7 and 8 in the Eclipse-based
+Spring Source Toolkit (STS) and therefore should run fine in any
+recent version of Eclipse or another IDE of your choice
+that supports Java 7 or later.
+
+### Building the Project
+You can also build the project using Maven outside of any IDE:
+```
+mvn clean install
+```
+
+### Running the tests
+The following test classes are in src/test/java in the package
+org.baeldung.spring.data.couchbase.service:
+- CampusRepositoryServiceTest
+- PersonRepositoryServiceTest
+- StudentRepositoryServiceTest
+
+These may be run as JUnit tests from your IDE
+or using the Maven command line:
+```
+mvn test
+```
diff --git a/spring-data-couchbase-2b/pom.xml b/spring-data-couchbase-2b/pom.xml
new file mode 100644
index 0000000000..7d58f78ce5
--- /dev/null
+++ b/spring-data-couchbase-2b/pom.xml
@@ -0,0 +1,105 @@
+
+ 4.0.0
+ org.baeldung
+ spring-data-couchbase-2b
+ 0.1-SNAPSHOT
+ spring-data-couchbase-2b
+ jar
+
+
+
+
+
+ org.springframework
+ spring-context
+ ${spring-framework.version}
+
+
+ org.springframework
+ spring-context-support
+ ${spring-framework.version}
+
+
+ org.springframework.data
+ spring-data-couchbase
+ ${spring-data-couchbase.version}
+
+
+
+
+ org.hibernate
+ hibernate-validator
+ ${hibernate-validator.version}
+
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+ compile
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${org.slf4j.version}
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${org.slf4j.version}
+
+
+
+
+ org.springframework
+ spring-test
+ ${spring-framework.version}
+ test
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+
+ 1.7
+
+
+
+
+
+
+ 1.7
+ UTF-8
+ 4.2.4.RELEASE
+ 2.1.1.RELEASE
+ 5.2.4.Final
+ 2.9.2
+ 1.1.3
+ 1.7.12
+ 4.11
+
+
+
+
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java
new file mode 100644
index 0000000000..8eeda08455
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java
@@ -0,0 +1,79 @@
+package org.baeldung.spring.data.couchbase;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Campus;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
+import org.springframework.data.couchbase.core.CouchbaseTemplate;
+import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
+import org.springframework.data.couchbase.core.query.Consistency;
+import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
+import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+
+import com.couchbase.client.java.Bucket;
+
+@Configuration
+@EnableCouchbaseRepositories(basePackages={"org.baeldung.spring.data.couchbase"})
+public class MyCouchbaseConfig extends AbstractCouchbaseConfiguration {
+
+ public static final List NODE_LIST = Arrays.asList("localhost");
+ public static final String DEFAULT_BUCKET_NAME = "baeldung";
+ public static final String DEFAULT_BUCKET_PASSWORD = "";
+
+ @Override
+ protected List getBootstrapHosts() {
+ return NODE_LIST;
+ }
+
+ @Override
+ protected String getBucketName() {
+ return DEFAULT_BUCKET_NAME;
+ }
+
+ @Override
+ protected String getBucketPassword() {
+ return DEFAULT_BUCKET_PASSWORD;
+ }
+
+ @Bean
+ public Bucket campusBucket() throws Exception {
+ return couchbaseCluster().openBucket("baeldung2", "");
+ }
+
+ @Bean
+ public CouchbaseTemplate campusTemplate() throws Exception {
+ CouchbaseTemplate template = new CouchbaseTemplate(
+ couchbaseClusterInfo(), campusBucket(),
+ mappingCouchbaseConverter(), translationService());
+ template.setDefaultConsistency(getDefaultConsistency());
+ return template;
+ }
+
+ @Override
+ public void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) {
+ try {
+ baseMapping.mapEntity(Campus.class, campusTemplate());
+ } catch (Exception e) {
+ //custom Exception handling
+ }
+ }
+
+ @Override
+ protected Consistency getDefaultConsistency() {
+ return Consistency.READ_YOUR_OWN_WRITES;
+ }
+
+ @Bean
+ public LocalValidatorFactoryBean localValidatorFactoryBean() {
+ return new LocalValidatorFactoryBean();
+ }
+
+ @Bean
+ public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() {
+ return new ValidatingCouchbaseEventListener(localValidatorFactoryBean());
+ }
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java
new file mode 100644
index 0000000000..201b14cf0b
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Campus.java
@@ -0,0 +1,102 @@
+package org.baeldung.spring.data.couchbase.model;
+
+import javax.validation.constraints.NotNull;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.couchbase.core.mapping.Document;
+import org.springframework.data.geo.Point;
+
+import com.couchbase.client.java.repository.annotation.Field;
+
+@Document
+public class Campus {
+
+ @Id
+ private String id;
+ @Field
+ @NotNull
+ private String name;
+ @Field
+ @NotNull
+ private Point location;
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Point getLocation() {
+ return location;
+ }
+ public void setLocation(Point location) {
+ this.location = location;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ if(id != null) {
+ hash = hash * 31 + id.hashCode();
+ }
+ if(name != null) {
+ hash = hash * 31 + name.hashCode();
+ }
+ if(location != null) {
+ hash = hash * 31 + location.hashCode();
+ }
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if((obj == null) || (obj.getClass() != this.getClass())) return false;
+ if(obj == this) return true;
+ Campus other = (Campus) obj;
+ return this.hashCode() == other.hashCode();
+ }
+
+ @SuppressWarnings("unused")
+ private Campus() {}
+
+ public Campus(Builder b) {
+ this.id = b.id;
+ this.name = b.name;
+ this.location = b.location;
+ }
+
+ public static class Builder {
+ private String id;
+ private String name;
+ private Point location;
+
+ public static Builder newInstance() {
+ return new Builder();
+ }
+
+ public Campus build() {
+ return new Campus(this);
+ }
+
+ public Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder location(Point location) {
+ this.location = location;
+ return this;
+ }
+ }
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java
new file mode 100644
index 0000000000..9220e157ed
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Person.java
@@ -0,0 +1,87 @@
+package org.baeldung.spring.data.couchbase.model;
+
+import javax.validation.constraints.NotNull;
+
+import org.joda.time.DateTime;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.couchbase.core.mapping.Document;
+
+import com.couchbase.client.java.repository.annotation.Field;
+
+@Document
+public class Person {
+
+ @Id
+ private String id;
+ @Field
+ @NotNull
+ private String firstName;
+ @Field
+ @NotNull
+ private String lastName;
+ @Field
+ @NotNull
+ private DateTime created;
+ @Field
+ private DateTime updated;
+
+ public Person(String id, String firstName, String lastName) {
+ this.id = id;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getFirstName() {
+ return firstName;
+ }
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+ public String getLastName() {
+ return lastName;
+ }
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+ public DateTime getCreated() {
+ return created;
+ }
+ public void setCreated(DateTime created) {
+ this.created = created;
+ }
+ public DateTime getUpdated() {
+ return updated;
+ }
+ public void setUpdated(DateTime updated) {
+ this.updated = updated;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ if(id != null) {
+ hash = hash * 31 + id.hashCode();
+ }
+ if(firstName != null) {
+ hash = hash * 31 + firstName.hashCode();
+ }
+ if(lastName != null) {
+ hash = hash * 31 + lastName.hashCode();
+ }
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if((obj == null) || (obj.getClass() != this.getClass())) return false;
+ if(obj == this) return true;
+ Person other = (Person) obj;
+ return this.hashCode() == other.hashCode();
+ }
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java
new file mode 100644
index 0000000000..9c266c2c62
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java
@@ -0,0 +1,113 @@
+package org.baeldung.spring.data.couchbase.model;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Past;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+import org.joda.time.DateTime;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Version;
+import org.springframework.data.couchbase.core.mapping.Document;
+
+import com.couchbase.client.java.repository.annotation.Field;
+
+@Document
+public class Student {
+ private static final String NAME_REGEX = "^[a-zA-Z .'-]+$";
+
+ @Id
+ private String id;
+ @Field
+ @NotNull
+ @Size(min=1, max=20)
+ @Pattern(regexp=NAME_REGEX)
+ private String firstName;
+ @Field
+ @NotNull
+ @Size(min=1, max=20)
+ @Pattern(regexp=NAME_REGEX)
+ private String lastName;
+ @Field
+ @Past
+ private DateTime dateOfBirth;
+ @Field
+ @NotNull
+ private DateTime created;
+ @Field
+ private DateTime updated;
+ @Version
+ private long version;
+
+ public Student() {}
+
+ public Student(String id, String firstName, String lastName, DateTime dateOfBirth) {
+ this.id = id;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.dateOfBirth = dateOfBirth;
+ }
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getFirstName() {
+ return firstName;
+ }
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+ public String getLastName() {
+ return lastName;
+ }
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+ public DateTime getDateOfBirth() {
+ return dateOfBirth;
+ }
+ public void setDateOfBirth(DateTime dateOfBirth) {
+ this.dateOfBirth = dateOfBirth;
+ }
+ public DateTime getCreated() {
+ return created;
+ }
+ public void setCreated(DateTime created) {
+ this.created = created;
+ }
+ public DateTime getUpdated() {
+ return updated;
+ }
+ public void setUpdated(DateTime updated) {
+ this.updated = updated;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ if(id != null) {
+ hash = hash * 31 + id.hashCode();
+ }
+ if(firstName != null) {
+ hash = hash * 31 + firstName.hashCode();
+ }
+ if(lastName != null) {
+ hash = hash * 31 + lastName.hashCode();
+ }
+ if(dateOfBirth != null) {
+ hash = hash * 31 + dateOfBirth.hashCode();
+ }
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if((obj == null) || (obj.getClass() != this.getClass())) return false;
+ if(obj == this) return true;
+ Student other = (Student) obj;
+ return this.hashCode() == other.hashCode();
+ }
+}
\ No newline at end of file
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java
new file mode 100644
index 0000000000..22b2fb2735
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/CampusRepository.java
@@ -0,0 +1,19 @@
+package org.baeldung.spring.data.couchbase.repos;
+
+import java.util.Set;
+
+import org.baeldung.spring.data.couchbase.model.Campus;
+import org.springframework.data.couchbase.core.query.Dimensional;
+import org.springframework.data.couchbase.core.query.View;
+import org.springframework.data.geo.Distance;
+import org.springframework.data.geo.Point;
+import org.springframework.data.repository.CrudRepository;
+
+public interface CampusRepository extends CrudRepository {
+
+ @View(designDocument="campus", viewName="byName")
+ Set findByName(String name);
+
+ @Dimensional(dimensions=2, designDocument="campus_spatial", spatialViewName="byLocation")
+ Set findByLocationNear(Point point, Distance distance);
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java
new file mode 100644
index 0000000000..14b77759e3
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/PersonRepository.java
@@ -0,0 +1,11 @@
+package org.baeldung.spring.data.couchbase.repos;
+
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Person;
+import org.springframework.data.repository.CrudRepository;
+
+public interface PersonRepository extends CrudRepository {
+ List findByFirstName(String firstName);
+ List findByLastName(String lastName);
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java
new file mode 100644
index 0000000000..433964c872
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java
@@ -0,0 +1,11 @@
+package org.baeldung.spring.data.couchbase.repos;
+
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Student;
+import org.springframework.data.repository.CrudRepository;
+
+public interface StudentRepository extends CrudRepository {
+ List findByFirstName(String firstName);
+ List findByLastName(String lastName);
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java
new file mode 100644
index 0000000000..d12e59ba1f
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryService.java
@@ -0,0 +1,54 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.baeldung.spring.data.couchbase.model.Campus;
+import org.baeldung.spring.data.couchbase.repos.CampusRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.geo.Distance;
+import org.springframework.data.geo.Point;
+import org.springframework.stereotype.Service;
+
+@Service
+@Qualifier("CampusRepositoryService")
+public class CampusRepositoryService implements CampusService {
+
+ private CampusRepository repo;
+ @Autowired
+ public void setCampusRepository(CampusRepository repo) {
+ this.repo = repo;
+ }
+
+ @Override
+ public Campus find(String id) {
+ return repo.findOne(id);
+ }
+
+ @Override
+ public Set findByName(String name) {
+ return repo.findByName(name);
+ }
+
+ @Override
+ public Set findByLocationNear(Point point, Distance distance) {
+ return repo.findByLocationNear(point, distance);
+ }
+
+ @Override
+ public Set findAll() {
+ Set campuses = new HashSet<>();
+ Iterator it = repo.findAll().iterator();
+ while(it.hasNext()) {
+ campuses.add(it.next());
+ }
+ return campuses;
+ }
+
+ @Override
+ public void save(Campus campus) {
+ repo.save(campus);
+ }
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java
new file mode 100644
index 0000000000..e82c14cb87
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/CampusService.java
@@ -0,0 +1,20 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import java.util.Set;
+
+import org.baeldung.spring.data.couchbase.model.Campus;
+import org.springframework.data.geo.Distance;
+import org.springframework.data.geo.Point;
+
+public interface CampusService {
+
+ Campus find(String id);
+
+ Set findByName(String name);
+
+ Set findByLocationNear(Point point, Distance distance);
+
+ Set findAll();
+
+ void save(Campus campus);
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java
new file mode 100644
index 0000000000..90cc36780a
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryService.java
@@ -0,0 +1,58 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Person;
+import org.baeldung.spring.data.couchbase.repos.PersonRepository;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+@Service
+@Qualifier("PersonRepositoryService")
+public class PersonRepositoryService implements PersonService {
+
+ private PersonRepository repo;
+ @Autowired
+ public void setPersonRepository(PersonRepository repo) {
+ this.repo = repo;
+ }
+
+ public Person findOne(String id) {
+ return repo.findOne(id);
+ }
+
+ public List findAll() {
+ List people = new ArrayList();
+ Iterator it = repo.findAll().iterator();
+ while(it.hasNext()) {
+ people.add(it.next());
+ }
+ return people;
+ }
+
+ public List findByFirstName(String firstName) {
+ return repo.findByFirstName(firstName);
+ }
+
+ public List findByLastName(String lastName) {
+ return repo.findByLastName(lastName);
+ }
+
+ public void create(Person person) {
+ person.setCreated(DateTime.now());
+ repo.save(person);
+ }
+
+ public void update(Person person) {
+ person.setUpdated(DateTime.now());
+ repo.save(person);
+ }
+
+ public void delete(Person person) {
+ repo.delete(person);
+ }
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java
new file mode 100644
index 0000000000..a823908b01
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/PersonService.java
@@ -0,0 +1,22 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Person;
+
+public interface PersonService {
+
+ Person findOne(String id);
+
+ List findAll();
+
+ List findByFirstName(String firstName);
+
+ List findByLastName(String lastName);
+
+ void create(Person person);
+
+ void update(Person person);
+
+ void delete(Person person);
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java
new file mode 100644
index 0000000000..58304afc1c
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java
@@ -0,0 +1,58 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Student;
+import org.baeldung.spring.data.couchbase.repos.StudentRepository;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+@Service
+@Qualifier("StudentRepositoryService")
+public class StudentRepositoryService implements StudentService {
+
+ private StudentRepository repo;
+ @Autowired
+ public void setStudentRepository(StudentRepository repo) {
+ this.repo = repo;
+ }
+
+ public Student findOne(String id) {
+ return repo.findOne(id);
+ }
+
+ public List findAll() {
+ List people = new ArrayList();
+ Iterator it = repo.findAll().iterator();
+ while(it.hasNext()) {
+ people.add(it.next());
+ }
+ return people;
+ }
+
+ public List findByFirstName(String firstName) {
+ return repo.findByFirstName(firstName);
+ }
+
+ public List findByLastName(String lastName) {
+ return repo.findByLastName(lastName);
+ }
+
+ public void create(Student student) {
+ student.setCreated(DateTime.now());
+ repo.save(student);
+ }
+
+ public void update(Student student) {
+ student.setUpdated(DateTime.now());
+ repo.save(student);
+ }
+
+ public void delete(Student student) {
+ repo.delete(student);
+ }
+}
diff --git a/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java
new file mode 100644
index 0000000000..f483ef0fb6
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java
@@ -0,0 +1,22 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.model.Student;
+
+public interface StudentService {
+
+ Student findOne(String id);
+
+ List findAll();
+
+ List findByFirstName(String firstName);
+
+ List findByLastName(String lastName);
+
+ void create(Student student);
+
+ void update(Student student);
+
+ void delete(Student student);
+}
diff --git a/spring-data-couchbase-2b/src/main/resources/logback.xml b/spring-data-couchbase-2b/src/main/resources/logback.xml
new file mode 100644
index 0000000000..d9067fd1da
--- /dev/null
+++ b/spring-data-couchbase-2b/src/main/resources/logback.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-data-couchbase-2b/src/site/site.xml b/spring-data-couchbase-2b/src/site/site.xml
new file mode 100644
index 0000000000..dda96feecd
--- /dev/null
+++ b/spring-data-couchbase-2b/src/site/site.xml
@@ -0,0 +1,25 @@
+
+
+
+
+ Spring Sample: ${project.name}
+ index.html
+
+
+
+ org.springframework.maven.skins
+ maven-spring-skin
+ 1.0.5
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java
new file mode 100644
index 0000000000..ce2daa92cd
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java
@@ -0,0 +1,13 @@
+package org.baeldung.spring.data.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 = { MyCouchbaseConfig.class, IntegrationTestConfig.class })
+@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
+public abstract class IntegrationTest {
+}
diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java
new file mode 100644
index 0000000000..6f040c34db
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTestConfig.java
@@ -0,0 +1,9 @@
+package org.baeldung.spring.data.couchbase;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = "org.baeldung.spring.data.couchbase")
+public class IntegrationTestConfig {
+}
diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java
new file mode 100644
index 0000000000..c298ef0a61
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java
@@ -0,0 +1,17 @@
+package org.baeldung.spring.data.couchbase;
+
+import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
+import org.springframework.data.couchbase.core.query.Consistency;
+
+public class TestCouchbaseConfig extends MyCouchbaseConfig {
+
+ @Override
+ public String typeKey() {
+ return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE;
+ }
+
+ @Override
+ public Consistency getDefaultConsistency() {
+ return Consistency.READ_YOUR_OWN_WRITES;
+ }
+}
diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java
new file mode 100644
index 0000000000..5a718f0807
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/CampusRepositoryServiceTest.java
@@ -0,0 +1,135 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import static org.junit.Assert.*;
+
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+
+import org.baeldung.spring.data.couchbase.IntegrationTest;
+import org.baeldung.spring.data.couchbase.model.Campus;
+import org.baeldung.spring.data.couchbase.repos.CampusRepository;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.geo.Distance;
+import org.springframework.data.geo.Metrics;
+import org.springframework.data.geo.Point;
+
+public class CampusRepositoryServiceTest extends IntegrationTest {
+
+ @Autowired
+ @Qualifier("CampusRepositoryService")
+ private CampusRepositoryService campusService;
+
+ @Autowired
+ private CampusRepository campusRepo;
+
+ private final Campus Brown = Campus.Builder.newInstance()
+ .id("campus:Brown")
+ .name("Brown")
+ .location(new Point(71.4025, 51.8268))
+ .build();
+
+ private final Campus Cornell = Campus.Builder.newInstance()
+ .id("campus:Cornell")
+ .name("Cornell")
+ .location(new Point(76.4833, 42.4459))
+ .build();
+
+ private final Campus Columbia = Campus.Builder.newInstance()
+ .id("campus:Columbia")
+ .name("Columbia")
+ .location(new Point(73.9626, 40.8075))
+ .build();
+
+ private final Campus Dartmouth = Campus.Builder.newInstance()
+ .id("campus:Dartmouth")
+ .name("Dartmouth")
+ .location(new Point(72.2887, 43.7044))
+ .build();
+
+ private final Campus Harvard = Campus.Builder.newInstance()
+ .id("campus:Harvard")
+ .name("Harvard")
+ .location(new Point(71.1167, 42.3770))
+ .build();
+
+ private final Campus Penn = Campus.Builder.newInstance()
+ .id("campus:Penn")
+ .name("Penn")
+ .location(new Point(75.1932, 39.9522))
+ .build();
+
+ private final Campus Princeton = Campus.Builder.newInstance()
+ .id("campus:Princeton")
+ .name("Princeton")
+ .location(new Point(74.6514, 40.3340))
+ .build();
+
+ private final Campus Yale = Campus.Builder.newInstance()
+ .id("campus:Yale")
+ .name("Yale")
+ .location(new Point(72.9223, 41.3163))
+ .build();
+
+ private final Point Boston = new Point(71.0589, 42.3601);
+ private final Point NewYorkCity = new Point(74.0059, 40.7128);
+
+ @PostConstruct
+ private void loadCampuses() throws Exception {
+ campusRepo.save(Brown);
+ campusRepo.save(Columbia);
+ campusRepo.save(Cornell);
+ campusRepo.save(Dartmouth);
+ campusRepo.save(Harvard);
+ campusRepo.save(Penn);
+ campusRepo.save(Princeton);
+ campusRepo.save(Yale);
+ }
+
+ @Test
+ public final void givenNameHarvard_whenFindByName_thenReturnsHarvard() throws Exception {
+ Set campuses = campusService.findByName(Harvard.getName());
+ assertNotNull(campuses);
+ assertFalse(campuses.isEmpty());
+ assertTrue(campuses.size() == 1);
+ assertTrue(campuses.contains(Harvard));
+ }
+
+ @Test
+ public final void givenHarvardId_whenFind_thenReturnsHarvard() throws Exception {
+ Campus actual = campusService.find(Harvard.getId());
+ assertNotNull(actual);
+ assertEquals(Harvard, actual);
+ }
+
+ @Test
+ public final void whenFindAll_thenReturnsAll() throws Exception {
+ Set campuses = campusService.findAll();
+ assertTrue(campuses.contains(Brown));
+ assertTrue(campuses.contains(Columbia));
+ assertTrue(campuses.contains(Cornell));
+ assertTrue(campuses.contains(Dartmouth));
+ assertTrue(campuses.contains(Harvard));
+ assertTrue(campuses.contains(Penn));
+ assertTrue(campuses.contains(Princeton));
+ assertTrue(campuses.contains(Yale));
+ }
+
+ @Test
+ public final void whenFindByLocationNearBoston_thenResultContainsHarvard() throws Exception {
+ Set campuses = campusService.findByLocationNear(Boston, new Distance(1, Metrics.NEUTRAL));
+ assertFalse(campuses.isEmpty());
+ assertTrue(campuses.contains(Harvard));
+ assertFalse(campuses.contains(Columbia));
+ }
+
+ @Test
+ public final void whenFindByLocationNearNewYorkCity_thenResultContainsColumbia() throws Exception {
+ Set campuses = campusService.findByLocationNear(NewYorkCity, new Distance(1, Metrics.NEUTRAL));
+ assertFalse(campuses.isEmpty());
+ assertTrue(campuses.contains(Columbia));
+ assertFalse(campuses.contains(Harvard));
+ }
+}
diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java
new file mode 100644
index 0000000000..84b6f75d56
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/PersonRepositoryServiceTest.java
@@ -0,0 +1,130 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.baeldung.spring.data.couchbase.IntegrationTest;
+import org.baeldung.spring.data.couchbase.MyCouchbaseConfig;
+import org.baeldung.spring.data.couchbase.model.Person;
+import org.joda.time.DateTime;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.document.json.JsonObject;
+
+public class PersonRepositoryServiceTest extends IntegrationTest {
+
+ private static final String typeField = "_class";
+ private static final String john = "John";
+ private static final String smith = "Smith";
+ private static final String johnSmithId = "person:" + john + ":" + smith;
+ private static final Person johnSmith = new Person(johnSmithId, john, smith);
+ private static final JsonObject jsonJohnSmith = JsonObject.empty()
+ .put(typeField, Person.class.getName())
+ .put("firstName", john)
+ .put("lastName", smith)
+ .put("created", DateTime.now().getMillis());
+
+ private static final String foo = "Foo";
+ private static final String bar = "Bar";
+ private static final String foobarId = "person:" + foo + ":" + bar;
+ private static final Person foobar = new Person(foobarId, foo, bar);
+ private static final JsonObject jsonFooBar = JsonObject.empty()
+ .put(typeField, Person.class.getName())
+ .put("firstName", foo)
+ .put("lastName", bar)
+ .put("created", DateTime.now().getMillis());
+
+ @Autowired
+ @Qualifier("PersonRepositoryService")
+ private PersonService personService;
+
+ @BeforeClass
+ public static void setupBeforeClass() {
+ Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST);
+ Bucket bucket = cluster.openBucket(MyCouchbaseConfig.DEFAULT_BUCKET_NAME, MyCouchbaseConfig.DEFAULT_BUCKET_PASSWORD);
+ bucket.upsert(JsonDocument.create(johnSmithId, jsonJohnSmith));
+ bucket.upsert(JsonDocument.create(foobarId, jsonFooBar));
+ bucket.close();
+ cluster.disconnect();
+ }
+
+ @Test
+ public void whenFindingPersonByJohnSmithId_thenReturnsJohnSmith() {
+ Person actualPerson = personService.findOne(johnSmithId);
+ assertNotNull(actualPerson);
+ assertNotNull(actualPerson.getCreated());
+ assertEquals(johnSmith, actualPerson);
+ }
+
+ @Test
+ public void whenFindingAllPersons_thenReturnsTwoOrMorePersonsIncludingJohnSmithAndFooBar() {
+ List resultList = personService.findAll();
+ assertNotNull(resultList);
+ assertFalse(resultList.isEmpty());
+ assertTrue(resultContains(resultList, johnSmith));
+ assertTrue(resultContains(resultList, foobar));
+ assertTrue(resultList.size() >= 2);
+ }
+
+ @Test
+ public void whenFindingByFirstNameJohn_thenReturnsOnlyPersonsNamedJohn() {
+ String expectedFirstName = john;
+ List resultList = personService.findByFirstName(expectedFirstName);
+ assertNotNull(resultList);
+ assertFalse(resultList.isEmpty());
+ assertTrue(allResultsContainExpectedFirstName(resultList, expectedFirstName));
+ }
+
+ @Test
+ public void whenFindingByLastNameSmith_thenReturnsOnlyPersonsNamedSmith() {
+ String expectedLastName = smith;
+ List resultList = personService.findByLastName(expectedLastName);
+ assertNotNull(resultList);
+ assertFalse(resultList.isEmpty());
+ assertTrue(allResultsContainExpectedLastName(resultList, expectedLastName));
+ }
+
+ private boolean resultContains(List resultList, Person person) {
+ boolean found = false;
+ for(Person p : resultList) {
+ if(p.equals(person)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ private boolean allResultsContainExpectedFirstName(List resultList, String firstName) {
+ boolean found = false;
+ for(Person p : resultList) {
+ if(p.getFirstName().equals(firstName)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ private boolean allResultsContainExpectedLastName(List resultList, String lastName) {
+ boolean found = false;
+ for(Person p : resultList) {
+ if(p.getLastName().equals(lastName)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+}
diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java
new file mode 100644
index 0000000000..166f01d754
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java
@@ -0,0 +1,170 @@
+package org.baeldung.spring.data.couchbase.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import javax.validation.ConstraintViolationException;
+
+import org.baeldung.spring.data.couchbase.IntegrationTest;
+import org.baeldung.spring.data.couchbase.MyCouchbaseConfig;
+import org.baeldung.spring.data.couchbase.model.Student;
+import org.joda.time.DateTime;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.document.json.JsonObject;
+
+public class StudentRepositoryServiceTest extends IntegrationTest {
+
+ private static final String typeField = "_class";
+ private static final String joe = "Joe";
+ private static final String college = "College";
+ private static final String joeCollegeId = "student:" + joe + ":" + college;
+ private static final DateTime joeCollegeDob = DateTime.now().minusYears(21);
+ private static final Student joeCollege = new Student(joeCollegeId, joe, college, joeCollegeDob);
+ private static final JsonObject jsonJoeCollege = JsonObject.empty()
+ .put(typeField, Student.class.getName())
+ .put("firstName", joe)
+ .put("lastName", college)
+ .put("created", DateTime.now().getMillis())
+ .put("version", 1);
+
+ private static final String judy = "Judy";
+ private static final String jetson = "Jetson";
+ private static final String judyJetsonId = "student:" + judy + ":" + jetson;
+ private static final DateTime judyJetsonDob = DateTime.now().minusYears(19).minusMonths(5).minusDays(3);
+ private static final Student judyJetson = new Student(judyJetsonId, judy, jetson, judyJetsonDob);
+ private static final JsonObject jsonJudyJetson = JsonObject.empty()
+ .put(typeField, Student.class.getName())
+ .put("firstName", judy)
+ .put("lastName", jetson)
+ .put("created", DateTime.now().getMillis())
+ .put("version", 1);
+
+ @Autowired
+ @Qualifier("StudentRepositoryService")
+ private StudentService studentService;
+
+ @BeforeClass
+ public static void setupBeforeClass() {
+ Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST);
+ Bucket bucket = cluster.openBucket(MyCouchbaseConfig.DEFAULT_BUCKET_NAME, MyCouchbaseConfig.DEFAULT_BUCKET_PASSWORD);
+ bucket.upsert(JsonDocument.create(joeCollegeId, jsonJoeCollege));
+ bucket.upsert(JsonDocument.create(judyJetsonId, jsonJudyJetson));
+ bucket.close();
+ cluster.disconnect();
+ }
+
+ @Test
+ public void whenCreatingStudent_thenDocumentIsPersisted() {
+ String firstName = "Eric";
+ String lastName = "Stratton";
+ DateTime dateOfBirth = DateTime.now().minusYears(25);
+ String id = "student:" + firstName + ":" + lastName;
+ Student expectedStudent = new Student(id, firstName, lastName, dateOfBirth);
+ studentService.create(expectedStudent);
+ Student actualStudent = studentService.findOne(id);
+ assertNotNull(actualStudent.getCreated());
+ assertNotNull(actualStudent);
+ assertEquals(expectedStudent.getId(), actualStudent.getId());
+ }
+
+ @Test(expected=ConstraintViolationException.class)
+ public void whenCreatingStudentWithInvalidFirstName_thenConstraintViolationException() {
+ String firstName = "Er+ic";
+ String lastName = "Stratton";
+ DateTime dateOfBirth = DateTime.now().minusYears(25);
+ String id = "student:" + firstName + ":" + lastName;
+ Student student = new Student(id, firstName, lastName, dateOfBirth);
+ studentService.create(student);
+ }
+
+ @Test(expected=ConstraintViolationException.class)
+ public void whenCreatingStudentWithFutureDob_thenConstraintViolationException() {
+ String firstName = "Jane";
+ String lastName = "Doe";
+ DateTime dateOfBirth = DateTime.now().plusDays(1);
+ String id = "student:" + firstName + ":" + lastName;
+ Student student = new Student(id, firstName, lastName, dateOfBirth);
+ studentService.create(student);
+ }
+
+ @Test
+ public void whenFindingStudentByJohnSmithId_thenReturnsJohnSmith() {
+ Student actualStudent = studentService.findOne(joeCollegeId);
+ assertNotNull(actualStudent);
+ assertNotNull(actualStudent.getCreated());
+ assertEquals(joeCollegeId, actualStudent.getId());
+ }
+
+ @Test
+ public void whenFindingAllStudents_thenReturnsTwoOrMoreStudentsIncludingJoeCollegeAndJudyJetson() {
+ List resultList = studentService.findAll();
+ assertNotNull(resultList);
+ assertFalse(resultList.isEmpty());
+ assertTrue(resultContains(resultList, joeCollege));
+ assertTrue(resultContains(resultList, judyJetson));
+ assertTrue(resultList.size() >= 2);
+ }
+
+ @Test
+ public void whenFindingByFirstNameJohn_thenReturnsOnlyStudentsNamedJohn() {
+ String expectedFirstName = joe;
+ List resultList = studentService.findByFirstName(expectedFirstName);
+ assertNotNull(resultList);
+ assertFalse(resultList.isEmpty());
+ assertTrue(allResultsContainExpectedFirstName(resultList, expectedFirstName));
+ }
+
+ @Test
+ public void whenFindingByLastNameSmith_thenReturnsOnlyStudentsNamedSmith() {
+ String expectedLastName = college;
+ List resultList = studentService.findByLastName(expectedLastName);
+ assertNotNull(resultList);
+ assertFalse(resultList.isEmpty());
+ assertTrue(allResultsContainExpectedLastName(resultList, expectedLastName));
+ }
+
+ private boolean resultContains(List resultList, Student student) {
+ boolean found = false;
+ for(Student p : resultList) {
+ if(p.getId().equals(student.getId())) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ private boolean allResultsContainExpectedFirstName(List resultList, String firstName) {
+ boolean found = false;
+ for(Student p : resultList) {
+ if(p.getFirstName().equals(firstName)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+
+ private boolean allResultsContainExpectedLastName(List resultList, String lastName) {
+ boolean found = false;
+ for(Student p : resultList) {
+ if(p.getLastName().equals(lastName)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+ }
+}
diff --git a/spring-data-couchbase-2b/src/test/resources/logback.xml b/spring-data-couchbase-2b/src/test/resources/logback.xml
new file mode 100644
index 0000000000..d9067fd1da
--- /dev/null
+++ b/spring-data-couchbase-2b/src/test/resources/logback.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml
index e796099190..33d6306c5a 100644
--- a/spring-mvc-java/pom.xml
+++ b/spring-mvc-java/pom.xml
@@ -194,7 +194,6 @@
cargo-maven2-plugin
${cargo-maven2-plugin.version}
- true
jetty8x
embedded
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/Company.java b/spring-mvc-java/src/main/java/com/baeldung/model/Company.java
new file mode 100644
index 0000000000..558507268a
--- /dev/null
+++ b/spring-mvc-java/src/main/java/com/baeldung/model/Company.java
@@ -0,0 +1,38 @@
+package com.baeldung.model;
+
+public class Company {
+
+ private long id;
+ private String name;
+
+ public Company() {
+ super();
+ }
+
+ public Company(final long id, final String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "Company [id=" + id + ", name=" + name + "]";
+ }
+
+}
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/Employee.java b/spring-mvc-java/src/main/java/com/baeldung/model/Employee.java
index d0f6b724eb..fb0a452219 100644
--- a/spring-mvc-java/src/main/java/com/baeldung/model/Employee.java
+++ b/spring-mvc-java/src/main/java/com/baeldung/model/Employee.java
@@ -8,15 +8,17 @@ public class Employee {
private long id;
private String name;
private String contactNumber;
+ private String workingArea;
public Employee() {
super();
}
- public Employee(final long id, final String name, final String contactNumber) {
+ public Employee(final long id, final String name, final String contactNumber, final String workingArea) {
this.id = id;
this.name = name;
this.contactNumber = contactNumber;
+ this.workingArea = workingArea;
}
public String getName() {
@@ -43,9 +45,17 @@ public class Employee {
this.contactNumber = contactNumber;
}
+ public String getWorkingArea() {
+ return workingArea;
+ }
+
+ public void setWorkingArea(final String workingArea) {
+ this.workingArea = workingArea;
+ }
+
@Override
public String toString() {
- return "Employee [id=" + id + ", name=" + name + ", contactNumber=" + contactNumber + "]";
+ return "Employee [id=" + id + ", name=" + name + ", contactNumber=" + contactNumber + ", workingArea=" + workingArea + "]";
}
}
diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java
index ba7f35fd65..663b9cc4d2 100644
--- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java
+++ b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java
@@ -13,12 +13,14 @@ import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.ResourceBundleViewResolver;
import org.springframework.web.servlet.view.XmlViewResolver;
+import org.springframework.web.util.UrlPathHelper;
@Configuration
@EnableWebMvc
@@ -96,4 +98,12 @@ public class WebConfig extends WebMvcConfigurerAdapter {
return list;
}
+
+ @Override
+ public void configurePathMatch(final PathMatchConfigurer configurer) {
+ final UrlPathHelper urlPathHelper = new UrlPathHelper();
+ urlPathHelper.setRemoveSemicolonContent(false);
+
+ configurer.setUrlPathHelper(urlPathHelper);
+ }
}
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/CompanyController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/CompanyController.java
new file mode 100644
index 0000000000..8228eafd5c
--- /dev/null
+++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/CompanyController.java
@@ -0,0 +1,56 @@
+package com.baeldung.web.controller;
+
+import com.baeldung.model.Company;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Controller
+public class CompanyController {
+
+ Map companyMap = new HashMap<>();
+
+ @RequestMapping(value = "/company", method = RequestMethod.GET)
+ public ModelAndView showForm() {
+ return new ModelAndView("companyHome", "company", new Company());
+ }
+
+ @RequestMapping(value = "/company/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET)
+ public @ResponseBody Company getCompanyById(@PathVariable final long Id) {
+ return companyMap.get(Id);
+ }
+
+ @RequestMapping(value = "/addCompany", method = RequestMethod.POST)
+ public String submit(@ModelAttribute("company") final Company company, final BindingResult result, final ModelMap model) {
+ if (result.hasErrors()) {
+ return "error";
+ }
+ model.addAttribute("name", company.getName());
+ model.addAttribute("id", company.getId());
+
+ companyMap.put(company.getId(), company);
+
+ return "companyView";
+ }
+
+ @RequestMapping(value = "/companyEmployee/{company}/employeeData/{employee}", method = RequestMethod.GET)
+ @ResponseBody
+ public ResponseEntity