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..0599aea457 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/enums/Pizza.java @@ -0,0 +1,84 @@ +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; + } + + private 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) { + EnumMap> map = pzList.stream().collect( + Collectors.groupingBy(Pizza::getStatus, + () -> new EnumMap>(PizzaStatusEnum.class), Collectors.toList())); + return map; + } + + 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..96b6314574 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.enums; + + +public enum PizzaDeliverySystemConfiguration { + INSTANCE ; + private 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/java_8_features/Address.java b/core-java-8/src/main/java/com/baeldung/java_8_features/Address.java new file mode 100644 index 0000000000..1f89503288 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/Address.java @@ -0,0 +1,14 @@ +package com.baeldung.java_8_features; + +public class Address { + + private String street; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/CustomException.java b/core-java-8/src/main/java/com/baeldung/java_8_features/CustomException.java new file mode 100644 index 0000000000..ff9be6ab06 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/CustomException.java @@ -0,0 +1,4 @@ +package com.baeldung.java_8_features; + +public class CustomException extends RuntimeException { +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java b/core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java new file mode 100644 index 0000000000..811937dba7 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java @@ -0,0 +1,13 @@ +package com.baeldung.java_8_features; + +import java.util.Arrays; +import java.util.List; + +public class Detail { + + private static final List PARTS = Arrays.asList("turbine", "pump"); + + public List getParts() { + return PARTS; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalAddress.java b/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalAddress.java new file mode 100644 index 0000000000..8d6c517ac5 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalAddress.java @@ -0,0 +1,16 @@ +package com.baeldung.java_8_features; + +import java.util.Optional; + +public class OptionalAddress { + + private String street; + + public Optional getStreet() { + return Optional.ofNullable(street); + } + + public void setStreet(String street) { + this.street = street; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalUser.java b/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalUser.java new file mode 100644 index 0000000000..ff06cd21d6 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalUser.java @@ -0,0 +1,16 @@ +package com.baeldung.java_8_features; + +import java.util.Optional; + +public class OptionalUser { + + private OptionalAddress address; + + public Optional getAddress() { + return Optional.of(address); + } + + public void setAddress(OptionalAddress address) { + this.address = address; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/User.java b/core-java-8/src/main/java/com/baeldung/java_8_features/User.java new file mode 100644 index 0000000000..3708d276c8 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/User.java @@ -0,0 +1,40 @@ +package com.baeldung.java_8_features; + +import java.util.Optional; + +public class User { + + private String name; + + private Address address; + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public User() { + } + + public User(String name) { + this.name = name; + } + + public static boolean isRealUser(User user) { + return true; + } + + public String getOrThrow() { + String value = null; + Optional valueOpt = Optional.ofNullable(value); + String result = valueOpt.orElseThrow(CustomException::new).toUpperCase(); + return result; + } + + public boolean isLegalName(String name) { + return name.length() > 3 && name.length() < 16; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Vehicle.java b/core-java-8/src/main/java/com/baeldung/java_8_features/Vehicle.java new file mode 100644 index 0000000000..011173bcaf --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/Vehicle.java @@ -0,0 +1,18 @@ +package com.baeldung.java_8_features; + +public interface Vehicle { + + void moveTo(long altitude, long longitude); + + static String producer() { + return "N&F Vehicles"; + } + + default long[] startPosition() { + return new long[]{23, 15}; + } + + default String getOverview() { + return "ATV made by " + producer(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/VehicleImpl.java b/core-java-8/src/main/java/com/baeldung/java_8_features/VehicleImpl.java new file mode 100644 index 0000000000..83e55f5f4d --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java_8_features/VehicleImpl.java @@ -0,0 +1,9 @@ +package com.baeldung.java_8_features; + +public class VehicleImpl implements Vehicle { + + @Override + public void moveTo(long altitude, long longitude) { + //do nothing + } +} 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..ca1c71043e --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java @@ -0,0 +1,78 @@ +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/Java8DefaultStaticIntefaceMethodsTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsTest.java new file mode 100644 index 0000000000..21a5e34b9b --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsTest.java @@ -0,0 +1,27 @@ +package com.baeldung.java8; + +import com.baeldung.java_8_features.Vehicle; +import com.baeldung.java_8_features.VehicleImpl; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class Java8DefaultStaticIntefaceMethodsTest { + + @Test + public void callStaticInterfaceMethdosMethods_whenExpectedResults_thenCorrect() { + Vehicle vehicle = new VehicleImpl(); + String overview = vehicle.getOverview(); + long[] startPosition = vehicle.startPosition(); + + assertEquals(overview, "ATV made by N&F Vehicles"); + assertEquals(startPosition[0], 23); + assertEquals(startPosition[1], 15); + } + + @Test + public void callDefaultInterfaceMethods_whenExpectedResults_thenCorrect() { + String producer = Vehicle.producer(); + assertEquals(producer, "N&F Vehicles"); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8MethodReferenceTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8MethodReferenceTest.java new file mode 100644 index 0000000000..d9d88c5052 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8MethodReferenceTest.java @@ -0,0 +1,67 @@ +package com.baeldung.java8; + +import com.baeldung.java_8_features.User; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class Java8MethodReferenceTest { + + private List list; + + @Before + public void init() { + list = new ArrayList<>(); + list.add("One"); + list.add("OneAndOnly"); + list.add("Derek"); + list.add("Change"); + list.add("factory"); + list.add("justBefore"); + list.add("Italy"); + list.add("Italy"); + list.add("Thursday"); + list.add(""); + list.add(""); + } + + @Test + public void checkStaticMethodReferences_whenWork_thenCorrect() { + + List users = new ArrayList<>(); + users.add(new User()); + users.add(new User()); + boolean isReal = users.stream().anyMatch(u -> User.isRealUser(u)); + boolean isRealRef = users.stream().anyMatch(User::isRealUser); + assertTrue(isReal); + assertTrue(isRealRef); + } + + @Test + public void checkInstanceMethodReferences_whenWork_thenCorrect() { + User user = new User(); + boolean isLegalName = list.stream().anyMatch(user::isLegalName); + assertTrue(isLegalName); + } + + @Test + public void checkParticularTypeReferences_whenWork_thenCorrect() { + long count = list.stream().filter(String::isEmpty).count(); + assertEquals(count, 2); + } + + @Test + public void checkConstructorReferences_whenWork_thenCorrect() { + Stream stream = list.stream().map(User::new); + List userList = stream.collect(Collectors.toList()); + assertEquals(userList.size(), list.size()); + assertTrue(userList.get(0) instanceof User); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8OptionalTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8OptionalTest.java new file mode 100644 index 0000000000..26de39bc0e --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8OptionalTest.java @@ -0,0 +1,118 @@ +package com.baeldung.java8; + +import com.baeldung.java_8_features.*; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.junit.Assert.*; + +public class Java8OptionalTest { + + private List list; + + @Before + public void init() { + list = new ArrayList<>(); + list.add("One"); + list.add("OneAndOnly"); + list.add("Derek"); + list.add("Change"); + list.add("factory"); + list.add("justBefore"); + list.add("Italy"); + list.add("Italy"); + list.add("Thursday"); + list.add(""); + list.add(""); + } + + @Test + public void checkOptional_whenAsExpected_thenCorrect() { + + Optional optionalEmpty = Optional.empty(); + assertFalse(optionalEmpty.isPresent()); + + String str = "value"; + Optional optional = Optional.of(str); + assertEquals(optional.get(), "value"); + + Optional optionalNullable = Optional.ofNullable(str); + Optional optionalNull = Optional.ofNullable(null); + assertEquals(optionalNullable.get(), "value"); + assertFalse(optionalNull.isPresent()); + + List listOpt = Optional.of(list).orElse(new ArrayList<>()); + List listNull = null; + List listOptNull = Optional.ofNullable(listNull).orElse(new ArrayList<>()); + assertTrue(listOpt == list); + assertTrue(listOptNull.isEmpty()); + + Optional user = Optional.ofNullable(getUser()); + String result = user.map(User::getAddress) + .map(Address::getStreet) + .orElse("not specified"); + assertEquals(result, "1st Avenue"); + + Optional optionalUser = Optional.ofNullable(getOptionalUser()); + String resultOpt = optionalUser.flatMap(OptionalUser::getAddress) + .flatMap(OptionalAddress::getStreet) + .orElse("not specified"); + assertEquals(resultOpt, "1st Avenue"); + + Optional userNull = Optional.ofNullable(getUserNull()); + String resultNull = userNull.map(User::getAddress) + .map(Address::getStreet) + .orElse("not specified"); + assertEquals(resultNull, "not specified"); + + Optional optionalUserNull = Optional.ofNullable(getOptionalUserNull()); + String resultOptNull = optionalUserNull.flatMap(OptionalUser::getAddress) + .flatMap(OptionalAddress::getStreet) + .orElse("not specified"); + assertEquals(resultOptNull, "not specified"); + + } + + @Test(expected = CustomException.class) + public void callMethod_whenCustomException_thenCorrect() { + User user = new User(); + String result = user.getOrThrow(); + } + + private User getUser() { + User user = new User(); + Address address = new Address(); + address.setStreet("1st Avenue"); + user.setAddress(address); + return user; + } + + private OptionalUser getOptionalUser() { + OptionalUser user = new OptionalUser(); + OptionalAddress address = new OptionalAddress(); + address.setStreet("1st Avenue"); + user.setAddress(address); + return user; + } + + private OptionalUser getOptionalUserNull() { + OptionalUser user = new OptionalUser(); + OptionalAddress address = new OptionalAddress(); + address.setStreet(null); + user.setAddress(address); + return user; + } + + private User getUserNull() { + User user = new User(); + Address address = new Address(); + address.setStreet(null); + user.setAddress(address); + return user; + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamsTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8StreamsTest.java new file mode 100644 index 0000000000..1f1dda49ce --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8StreamsTest.java @@ -0,0 +1,113 @@ +package com.baeldung.java8; + +import com.baeldung.java_8_features.Detail; +import org.junit.Before; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.*; + +public class Java8StreamsTest { + + private List list; + + @Before + public void init() { + list = new ArrayList<>(); + list.add("One"); + list.add("OneAndOnly"); + list.add("Derek"); + list.add("Change"); + list.add("factory"); + list.add("justBefore"); + list.add("Italy"); + list.add("Italy"); + list.add("Thursday"); + list.add(""); + list.add(""); + } + + @Test + public void checkStreamCount_whenCreating_givenDifferentSources() { + String[] arr = new String[]{"a", "b", "c"}; + Stream streamArr = Arrays.stream(arr); + assertEquals(streamArr.count(), 3); + + Stream streamOf = Stream.of("a", "b", "c"); + assertEquals(streamOf.count(), 3); + + long count = list.stream().distinct().count(); + assertEquals(count, 9); + } + + + @Test + public void checkStreamCount_whenOperationFilter_thanCorrect() { + Stream streamFilter = list.stream().filter(element -> element.isEmpty()); + assertEquals(streamFilter.count(), 2); + } + + + @Test + public void checkStreamCount_whenOperationMap_thanCorrect() { + List uris = new ArrayList<>(); + uris.add("C:\\My.txt"); + Stream streamMap = uris.stream().map(uri -> Paths.get(uri)); + assertEquals(streamMap.count(), 1); + + List details = new ArrayList<>(); + details.add(new Detail()); + details.add(new Detail()); + Stream streamFlatMap = details.stream() + .flatMap(detail -> detail.getParts().stream()); + assertEquals(streamFlatMap.count(), 4); + } + + + @Test + public void checkStreamCount_whenOperationMatch_thenCorrect() { + boolean isValid = list.stream().anyMatch(element -> element.contains("h")); + boolean isValidOne = list.stream().allMatch(element -> element.contains("h")); + boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h")); + assertTrue(isValid); + assertFalse(isValidOne); + assertFalse(isValidTwo); + } + + + @Test + public void checkStreamReducedValue_whenOperationReduce_thenCorrect() { + List integers = new ArrayList<>(); + integers.add(1); + integers.add(1); + integers.add(1); + Integer reduced = integers.stream().reduce(23, (a, b) -> a + b); + assertTrue(reduced == 26); + } + + @Test + public void checkStreamContains_whenOperationCollect_thenCorrect() { + List resultList = list.stream() + .map(element -> element.toUpperCase()) + .collect(Collectors.toList()); + assertEquals(resultList.size(), list.size()); + assertTrue(resultList.contains("")); + } + + + @Test + public void checkParallelStream_whenDoWork() { + list.parallelStream().forEach(element -> doWork(element)); + } + + private void doWork(String string) { + assertTrue(true); //just imitate an amount of work + } +} diff --git a/core-java/pom.xml b/core-java/pom.xml index e3a9043b09..39cb79a86a 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 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..b1c90b42cf --- /dev/null +++ b/core-java/src/main/java/com/baeldung/enums/Pizza.java @@ -0,0 +1,117 @@ +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.CollectionUtils; +import org.apache.commons.collections15.Predicate; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +public class Pizza { + + private static EnumSet undeliveredPizzaStatuses = + EnumSet.of(PizzaStatusEnum.ORDERED, PizzaStatusEnum.READY); + + private PizzaStatusEnum status; + + @JsonFormat(shape = JsonFormat.Shape.OBJECT) + 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;} + @JsonProperty("timeToDelivery") + public int getTimeToDelivery() { + return timeToDelivery; + } + + private 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 getAllUndeliveredPizza(List input) { + List undelivered = input; + CollectionUtils.filter(undelivered, thatAreNotDelivered()); + return undelivered; + } + + public static EnumMap> groupPizzaByStatus(List pizzaList) { + EnumMap> pzByStatus = new EnumMap>(PizzaStatusEnum.class); + for (Pizza pz : pizzaList) { + PizzaStatusEnum status = pz.getStatus(); + + if (pzByStatus.containsKey(status)) { + pzByStatus.get(status).add(pz); + } else { + List newPzList = new ArrayList(); + newPzList.add(pz); + pzByStatus.put(status, newPzList); + } + } + return pzByStatus; + } + + public void deliver() { + if (isDeliverable()) { + PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy().deliver(this); + this.setStatus(PizzaStatusEnum.DELIVERED); + } + } + + public static String getJsonString(Pizza pz) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(pz); + } + + private static Predicate thatAreNotDelivered() { + return new Predicate() { + public boolean evaluate(Pizza entry) { + return 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..9210945783 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java @@ -0,0 +1,20 @@ +package com.baeldung.enums; + +public enum PizzaDeliverySystemConfiguration { + INSTANCE ; + private 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..9f6a8feae5 --- /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.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.getAllUndeliveredPizza(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/jsf/.gitignore b/jsf/.gitignore new file mode 100644 index 0000000000..d1c20ca0f1 --- /dev/null +++ b/jsf/.gitignore @@ -0,0 +1,2 @@ +/target +*.iml diff --git a/jsf/pom.xml b/jsf/pom.xml new file mode 100644 index 0000000000..2f5d315e41 --- /dev/null +++ b/jsf/pom.xml @@ -0,0 +1,116 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + 4.0.0 + + jsf + 0.1-SNAPSHOT + war + + + + + com.sun.faces + jsf-api + ${com.sun.faces.version} + + + com.sun.faces + jsf-impl + ${com.sun.faces.version} + + + + + + org.springframework + spring-web + ${org.springframework.version} + + + org.springframework + spring-webmvc + ${org.springframework.version} + + + org.springframework + spring-websocket + ${org.springframework.version} + + + org.springframework + spring-messaging + ${org.springframework.version} + + + org.springframework + spring-web + ${org.springframework.version} + + + javax.servlet + javax.servlet-api + provided + ${javax.servlet.version} + + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + + + + + 4.2.5.RELEASE + + + 2.1.7 + + + 1.7.13 + 1.1.3 + + + 3.1.0 + + \ No newline at end of file diff --git a/jsf/src/main/java/com/baeldung/springintegration/config/MainWebAppInitializer.java b/jsf/src/main/java/com/baeldung/springintegration/config/MainWebAppInitializer.java new file mode 100644 index 0000000000..2de647915c --- /dev/null +++ b/jsf/src/main/java/com/baeldung/springintegration/config/MainWebAppInitializer.java @@ -0,0 +1,36 @@ +package com.baeldung.springintegration.config; + +import com.sun.faces.config.FacesInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import java.util.Set; + +public class MainWebAppInitializer extends FacesInitializer implements WebApplicationInitializer { + private static final Logger LOGGER = LoggerFactory.getLogger(MainWebAppInitializer.class); + + @Override + public void onStartup(Set> classes, ServletContext servletContext) throws ServletException { + super.onStartup(classes, servletContext); + } + + /** + * Register and configure all Servlet container components necessary to power the web application. + */ + @Override + public void onStartup(final ServletContext sc) throws ServletException { + LOGGER.info("MainWebAppInitializer.onStartup()"); + sc.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", "true"); + + // Create the 'root' Spring application context + final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); + root.register(SpringCoreConfig.class); + sc.addListener(new ContextLoaderListener(root)); + } + +} diff --git a/jsf/src/main/java/com/baeldung/springintegration/config/SpringCoreConfig.java b/jsf/src/main/java/com/baeldung/springintegration/config/SpringCoreConfig.java new file mode 100644 index 0000000000..a39da3fe25 --- /dev/null +++ b/jsf/src/main/java/com/baeldung/springintegration/config/SpringCoreConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.springintegration.config; + +import com.baeldung.springintegration.dao.UserManagementDAO; +import com.baeldung.springintegration.dao.UserManagementDAOImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringCoreConfig { + + @Bean + public UserManagementDAO userManagementDAO() { + return new UserManagementDAOImpl(); + } +} diff --git a/jsf/src/main/java/com/baeldung/springintegration/controllers/RegistrationBean.java b/jsf/src/main/java/com/baeldung/springintegration/controllers/RegistrationBean.java new file mode 100644 index 0000000000..cf8dab5289 --- /dev/null +++ b/jsf/src/main/java/com/baeldung/springintegration/controllers/RegistrationBean.java @@ -0,0 +1,62 @@ +package com.baeldung.springintegration.controllers; + +import com.baeldung.springintegration.dao.UserManagementDAO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ManagedProperty; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; +import java.io.Serializable; + +@ManagedBean(name = "registration") +@ViewScoped +public class RegistrationBean implements Serializable { + private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationBean.class); + + @ManagedProperty(value = "#{userManagementDAO}") + transient private UserManagementDAO userDao; + private String userName; + private String operationMessage; + + public void createNewUser() { + try { + LOGGER.info("Creating new user"); + FacesContext context = FacesContext.getCurrentInstance(); + boolean operationStatus = userDao.createUser(userName); + context.isValidationFailed(); + if (operationStatus) { + operationMessage = "User " + userName + " created"; + } + } catch (Exception ex) { + LOGGER.error("Error registering new user "); + ex.printStackTrace(); + operationMessage = "Error " + userName + " not created"; + } + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public void setUserDao(UserManagementDAO userDao) { + this.userDao = userDao; + } + + public UserManagementDAO getUserDao() { + return this.userDao; + } + + public String getOperationMessage() { + return operationMessage; + } + + public void setOperationMessage(String operationMessage) { + this.operationMessage = operationMessage; + } +} diff --git a/jsf/src/main/java/com/baeldung/springintegration/dao/UserManagementDAO.java b/jsf/src/main/java/com/baeldung/springintegration/dao/UserManagementDAO.java new file mode 100644 index 0000000000..2acb4e636d --- /dev/null +++ b/jsf/src/main/java/com/baeldung/springintegration/dao/UserManagementDAO.java @@ -0,0 +1,7 @@ +package com.baeldung.springintegration.dao; + +public interface UserManagementDAO { + + boolean createUser(String newUserData); + +} diff --git a/jsf/src/main/java/com/baeldung/springintegration/dao/UserManagementDAOImpl.java b/jsf/src/main/java/com/baeldung/springintegration/dao/UserManagementDAOImpl.java new file mode 100644 index 0000000000..56cbdd7b88 --- /dev/null +++ b/jsf/src/main/java/com/baeldung/springintegration/dao/UserManagementDAOImpl.java @@ -0,0 +1,38 @@ +package com.baeldung.springintegration.dao; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; +import javax.annotation.PostConstruct; + +@Repository +public class UserManagementDAOImpl implements UserManagementDAO { + private static final Logger LOGGER = LoggerFactory.getLogger(UserManagementDAOImpl.class); + + private List users; + + @PostConstruct + public void initUserList() { + users = new ArrayList<>(); + } + + @Override + public boolean createUser(String newUserData) { + if (newUserData != null) { + users.add(newUserData); + LOGGER.info("User {} successfully created", newUserData); + return true; + } else { + return false; + } + } + + public UserManagementDAOImpl() { + } + + +} diff --git a/jsf/src/main/resources/logback.xml b/jsf/src/main/resources/logback.xml new file mode 100644 index 0000000000..e9ae1894a6 --- /dev/null +++ b/jsf/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + \ No newline at end of file diff --git a/jsf/src/main/resources/messages.properties b/jsf/src/main/resources/messages.properties new file mode 100644 index 0000000000..41e9622630 --- /dev/null +++ b/jsf/src/main/resources/messages.properties @@ -0,0 +1,3 @@ +message.valueRequired = This value is required +message.welcome = Baeldung | Register +label.saveButton = Save diff --git a/jsf/src/main/webapp/META-INF/context.xml b/jsf/src/main/webapp/META-INF/context.xml new file mode 100644 index 0000000000..cf746bfae4 --- /dev/null +++ b/jsf/src/main/webapp/META-INF/context.xml @@ -0,0 +1,2 @@ + + diff --git a/jsf/src/main/webapp/WEB-INF/faces-config.xml b/jsf/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000000..e9e6404b95 --- /dev/null +++ b/jsf/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,39 @@ + + + + + + + + + + messages + + + msg + + + + + constraints + + + constraints + + + org.springframework.web.jsf.el.SpringBeanFacesELResolver + + + + /* + + home + /index.xhtml + + + + + diff --git a/jsf/src/main/webapp/index.xhtml b/jsf/src/main/webapp/index.xhtml new file mode 100644 index 0000000000..b37c864f2c --- /dev/null +++ b/jsf/src/main/webapp/index.xhtml @@ -0,0 +1,28 @@ + + + + + <h:outputText value="#{msg['message.welcome']}"/> + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 6f63269248..d6a1d7c034 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ spring-security-rest-full spring-thymeleaf spring-zuul + jsf diff --git a/spring-data-couchbase-2/.classpath b/spring-data-couchbase-2/.classpath index f4c34adf1f..679a31b6da 100644 --- a/spring-data-couchbase-2/.classpath +++ b/spring-data-couchbase-2/.classpath @@ -4,7 +4,7 @@ - + diff --git a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java index 5c0b1a93ca..8e6b971dbf 100644 --- a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java +++ b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/MyCouchbaseConfig.java @@ -3,9 +3,13 @@ package org.baeldung.spring.data.couchbase; import java.util.Arrays; import java.util.List; +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.mapping.event.ValidatingCouchbaseEventListener; +import org.springframework.data.couchbase.core.query.Consistency; import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; @Configuration @EnableCouchbaseRepositories(basePackages={"org.baeldung.spring.data.couchbase"}) @@ -29,4 +33,19 @@ public class MyCouchbaseConfig extends AbstractCouchbaseConfiguration { protected String getBucketPassword() { return BUCKET_PASSWORD; } + + @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-2/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/model/Student.java new file mode 100644 index 0000000000..9c266c2c62 --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/repos/CustomStudentRepository.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/CustomStudentRepository.java new file mode 100644 index 0000000000..9a5bf21492 --- /dev/null +++ b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/CustomStudentRepository.java @@ -0,0 +1,9 @@ +package org.baeldung.spring.data.couchbase.repos; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Student; + +public interface CustomStudentRepository { + List findByFirstNameStartsWith(String s); +} diff --git a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java new file mode 100644 index 0000000000..66b672a4fd --- /dev/null +++ b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java @@ -0,0 +1,25 @@ +package org.baeldung.spring.data.couchbase.repos; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Student; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.couchbase.core.CouchbaseTemplate; + +import com.couchbase.client.java.view.Stale; +import com.couchbase.client.java.view.ViewQuery; + +public class CustomStudentRepositoryImpl implements CustomStudentRepository { + + private static final String DESIGN_DOC = "student"; + + @Autowired + private CouchbaseTemplate template; + + public List findByFirstNameStartsWith(String s) { + return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName") + .startKey(s) + .stale(Stale.FALSE), + Student.class); + } +} diff --git a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/repos/StudentRepository.java new file mode 100644 index 0000000000..331ddc553d --- /dev/null +++ b/spring-data-couchbase-2/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, CustomStudentRepository { + List findByFirstName(String firstName); + List findByLastName(String lastName); +} diff --git a/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryService.java new file mode 100644 index 0000000000..58304afc1c --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentService.java new file mode 100644 index 0000000000..f483ef0fb6 --- /dev/null +++ b/spring-data-couchbase-2/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-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentTemplateService.java b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentTemplateService.java new file mode 100644 index 0000000000..c3808e0015 --- /dev/null +++ b/spring-data-couchbase-2/src/main/java/org/baeldung/spring/data/couchbase/service/StudentTemplateService.java @@ -0,0 +1,55 @@ +package org.baeldung.spring.data.couchbase.service; + +import java.util.List; + +import org.baeldung.spring.data.couchbase.model.Student; +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.couchbase.core.CouchbaseTemplate; +import org.springframework.stereotype.Service; + +import com.couchbase.client.java.view.ViewQuery; + +@Service +@Qualifier("StudentTemplateService") +public class StudentTemplateService implements StudentService { + + private static final String DESIGN_DOC = "student"; + + private CouchbaseTemplate template; + @Autowired + public void setCouchbaseTemplate(CouchbaseTemplate template) { + this.template = template; + } + + public Student findOne(String id) { + return template.findById(id, Student.class); + } + + public List findAll() { + return template.findByView(ViewQuery.from(DESIGN_DOC, "all"), Student.class); + } + + public List findByFirstName(String firstName) { + return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName"), Student.class); + } + + public List findByLastName(String lastName) { + return template.findByView(ViewQuery.from(DESIGN_DOC, "byLastName"), Student.class); + } + + public void create(Student student) { + student.setCreated(DateTime.now()); + template.insert(student); + } + + public void update(Student student) { + student.setUpdated(DateTime.now()); + template.update(student); + } + + public void delete(Student student) { + template.remove(student); + } +} diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java index 4edfb165bf..c298ef0a61 100644 --- a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/TestCouchbaseConfig.java @@ -1,6 +1,7 @@ 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 { @@ -8,4 +9,9 @@ public class TestCouchbaseConfig extends MyCouchbaseConfig { public String typeKey() { return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE; } + + @Override + public Consistency getDefaultConsistency() { + return Consistency.READ_YOUR_OWN_WRITES; + } } diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java new file mode 100644 index 0000000000..040453fd73 --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentRepositoryServiceTest.java @@ -0,0 +1,13 @@ +package org.baeldung.spring.data.couchbase.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class StudentRepositoryServiceTest extends StudentServiceTest { + + @Autowired + @Qualifier("StudentRepositoryService") + public void setStudentService(StudentService service) { + this.studentService = service; + } +} diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentServiceTest.java new file mode 100644 index 0000000000..79948cbedf --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentServiceTest.java @@ -0,0 +1,166 @@ +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 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 abstract class StudentServiceTest extends IntegrationTest { + + static final String typeField = "_class"; + static final String joe = "Joe"; + static final String college = "College"; + static final String joeCollegeId = "student:" + joe + ":" + college; + static final DateTime joeCollegeDob = DateTime.now().minusYears(21); + static final Student joeCollege = new Student(joeCollegeId, joe, college, joeCollegeDob); + 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); + + static final String judy = "Judy"; + static final String jetson = "Jetson"; + static final String judyJetsonId = "student:" + judy + ":" + jetson; + static final DateTime judyJetsonDob = DateTime.now().minusYears(19).minusMonths(5).minusDays(3); + static final Student judyJetson = new Student(judyJetsonId, judy, jetson, judyJetsonDob); + 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); + + StudentService studentService; + + @BeforeClass + public static void setupBeforeClass() { + Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST); + Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.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-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentTemplateServiceTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentTemplateServiceTest.java new file mode 100644 index 0000000000..dd5be8e059 --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/spring/data/couchbase/service/StudentTemplateServiceTest.java @@ -0,0 +1,13 @@ +package org.baeldung.spring.data.couchbase.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class StudentTemplateServiceTest extends StudentServiceTest { + + @Autowired + @Qualifier("StudentTemplateService") + public void setStudentService(StudentService service) { + this.studentService = service; + } +} diff --git a/spring-data-elasticsearch/.classpath b/spring-data-elasticsearch/.classpath new file mode 100644 index 0000000000..6d7587a819 --- /dev/null +++ b/spring-data-elasticsearch/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-elasticsearch/.project b/spring-data-elasticsearch/.project new file mode 100644 index 0000000000..09b9a781ed --- /dev/null +++ b/spring-data-elasticsearch/.project @@ -0,0 +1,29 @@ + + + spring-data-elasticsearch + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + + org.springframework.ide.eclipse.core.springnature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/spring-data-elasticsearch/pom.xml b/spring-data-elasticsearch/pom.xml index 27fb521dbc..3a6e330564 100644 --- a/spring-data-elasticsearch/pom.xml +++ b/spring-data-elasticsearch/pom.xml @@ -18,7 +18,7 @@ 4.11 1.7.12 1.1.3 - 1.3.2.RELEASE + 2.0.1.RELEASE @@ -44,6 +44,11 @@ spring-data-elasticsearch ${elasticsearch.version} + net.java.dev.jna + jna + 4.1.0 + test + org.slf4j slf4j-api diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java index 3857056b70..f93999a1cc 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java @@ -1,10 +1,16 @@ package com.baeldung.spring.data.es.config; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + import org.elasticsearch.client.Client; -import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.node.NodeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -12,35 +18,33 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - @Configuration @EnableElasticsearchRepositories(basePackages = "com.baeldung.spring.data.es.repository") -@ComponentScan(basePackages = {"com.baeldung.spring.data.es.service"}) +@ComponentScan(basePackages = { "com.baeldung.spring.data.es.service" }) public class Config { + @Value("${elasticsearch.home:/usr/local/Cellar/elasticsearch/2.3.2}") + private String elasticsearchHome; + private static Logger logger = LoggerFactory.getLogger(Config.class); @Bean public Client client() { try { - Path tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), "elasticsearch_data"); + final Path tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), "elasticsearch_data"); - ImmutableSettings.Builder elasticsearchSettings = ImmutableSettings.settingsBuilder() - .put("http.enabled", "false") - .put("path.data", tmpDir.toAbsolutePath().toString()); + // @formatter:off + + final Settings.Builder elasticsearchSettings = + Settings.settingsBuilder().put("http.enabled", "false") + .put("path.data", tmpDir.toAbsolutePath().toString()) + .put("path.home", elasticsearchHome); + // @formatter:on logger.debug(tmpDir.toAbsolutePath().toString()); - return new NodeBuilder() - .local(true) - .settings(elasticsearchSettings.build()) - .node() - .client(); - } catch (IOException ioex) { + return new NodeBuilder().local(true).settings(elasticsearchSettings.build()).node().client(); + } catch (final IOException ioex) { logger.error("Cannot create temp dir", ioex); throw new RuntimeException(); } diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java index 40db51ac13..01330a6c9c 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java @@ -1,27 +1,25 @@ package com.baeldung.spring.data.es.model; -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.annotations.*; - -import java.util.Arrays; -import java.util.List; - import static org.springframework.data.elasticsearch.annotations.FieldIndex.not_analyzed; import static org.springframework.data.elasticsearch.annotations.FieldType.Nested; import static org.springframework.data.elasticsearch.annotations.FieldType.String; +import java.util.Arrays; +import java.util.List; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.MultiField; + @Document(indexName = "blog", type = "article") public class Article { @Id private String id; - @MultiField( - mainField = @Field(type = String), - otherFields = { - @NestedField(index = not_analyzed, dotSuffix = "verbatim", type = String) - } - ) + @MultiField(mainField = @Field(type = String), otherFields = { @InnerField(index = not_analyzed, suffix = "verbatim", type = String) }) private String title; @Field(type = Nested) @@ -71,11 +69,6 @@ public class Article { @Override public String toString() { - return "Article{" + - "id='" + id + '\'' + - ", title='" + title + '\'' + - ", authors=" + authors + - ", tags=" + Arrays.toString(tags) + - '}'; + return "Article{" + "id='" + id + '\'' + ", title='" + title + '\'' + ", authors=" + authors + ", tags=" + Arrays.toString(tags) + '}'; } } diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Author.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Author.java index c335c4534a..38f50e1614 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Author.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Author.java @@ -21,8 +21,6 @@ public class Author { @Override public String toString() { - return "Author{" + - "name='" + name + '\'' + - '}'; + return "Author{" + "name='" + name + '\'' + '}'; } } diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java index 760bad4b01..b5a8fde633 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java @@ -6,10 +6,16 @@ import org.springframework.data.domain.Pageable; public interface ArticleService { Article save(Article article); + Article findOne(String id); + Iterable
findAll(); + Page
findByAuthorName(String name, Pageable pageable); + Page
findByAuthorNameUsingCustomQuery(String name, Pageable pageable); + long count(); + void delete(Article article); } diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java index 3bb6e6a0e0..0ea922bdd3 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java @@ -49,6 +49,6 @@ public class ArticleServiceImpl implements ArticleService { @Override public void delete(Article article) { - articleRepository.delete(article); + articleRepository.delete(article); } } diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryTest.java index fbc18cbb4c..1551d6442e 100644 --- a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryTest.java +++ b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryTest.java @@ -1,12 +1,20 @@ package com.baeldung.spring.data.es; -import com.baeldung.spring.data.es.config.Config; -import com.baeldung.spring.data.es.model.Article; -import com.baeldung.spring.data.es.model.Author; -import com.baeldung.spring.data.es.service.ArticleService; -import org.elasticsearch.action.ActionFuture; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.index.IndexResponse; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND; +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery; +import static org.elasticsearch.index.query.QueryBuilders.nestedQuery; +import static org.elasticsearch.index.query.QueryBuilders.termQuery; +import static org.junit.Assert.assertEquals; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.common.unit.Fuzziness; @@ -28,19 +36,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import static java.util.Arrays.asList; -import static java.util.stream.Collectors.toList; -import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND; -import static org.elasticsearch.index.query.QueryBuilders.*; -import static org.junit.Assert.assertEquals; +import com.baeldung.spring.data.es.config.Config; +import com.baeldung.spring.data.es.model.Article; +import com.baeldung.spring.data.es.model.Author; +import com.baeldung.spring.data.es.service.ArticleService; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {Config.class}, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { Config.class }, loader = AnnotationConfigContextLoader.class) public class ElasticSearchQueryTest { @Autowired @@ -60,7 +62,7 @@ public class ElasticSearchQueryTest { elasticsearchTemplate.deleteIndex(Article.class); elasticsearchTemplate.createIndex(Article.class); elasticsearchTemplate.putMapping(Article.class); - elasticsearchTemplate.refresh(Article.class, true); + elasticsearchTemplate.refresh(Article.class); Article article = new Article("Spring Data Elasticsearch"); article.setAuthors(asList(johnSmith, johnDoe)); @@ -85,127 +87,92 @@ public class ElasticSearchQueryTest { @Test public void givenFullTitle_whenRunMatchQuery_thenDocIsFound() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title", "Search engines").operator(AND)) - .build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND)).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); } @Test public void givenOneTermFromTitle_whenRunMatchQuery_thenDocIsFound() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title", "Engines Solutions")) - .build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Engines Solutions")).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); assertEquals("Search engines", articles.get(0).getTitle()); } @Test public void givenPartTitle_whenRunMatchQuery_thenDocIsFound() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title", "elasticsearch data")) - .build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "elasticsearch data")).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(3, articles.size()); } @Test public void givenFullTitle_whenRunMatchQueryOnVerbatimField_thenDocIsFound() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch")) - .build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch")).build(); + List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); - searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title.verbatim", "Second Article About")) - .build(); - articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About")).build(); + articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(0, articles.size()); } @Test public void givenNestedObject_whenQueryByAuthorsName_thenFoundArticlesByThatAuthor() { - QueryBuilder builder = nestedQuery("authors", - boolQuery().must(termQuery("authors.name", "smith"))); + final QueryBuilder builder = nestedQuery("authors", boolQuery().must(termQuery("authors.name", "smith"))); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(2, articles.size()); } @Test public void givenAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTokenCountsSeparately() { - TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("title"); - SearchResponse response = client.prepareSearch("blog").setTypes("article") - .addAggregation(aggregation).execute().actionGet(); + final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("title"); + final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation).execute().actionGet(); - Map results = response.getAggregations().asMap(); - StringTerms topTags = (StringTerms) results.get("top_tags"); + final Map results = response.getAggregations().asMap(); + final StringTerms topTags = (StringTerms) results.get("top_tags"); - List keys = topTags.getBuckets().stream().map(b -> b.getKey()).collect(toList()); + final List keys = topTags.getBuckets().stream().map(b -> b.getKeyAsString()).collect(toList()); Collections.sort(keys); - assertEquals(asList("about", "article", "data", "elasticsearch", - "engines", "search", "second", "spring", "tutorial"), keys); + assertEquals(asList("about", "article", "data", "elasticsearch", "engines", "search", "second", "spring", "tutorial"), keys); } @Test public void givenNotAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTermCountsIndividually() { - TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags") - .order(Terms.Order.aggregation("_count", false)); - SearchResponse response = client.prepareSearch("blog").setTypes("article") - .addAggregation(aggregation).execute().actionGet(); + final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags").order(Terms.Order.aggregation("_count", false)); + final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation).execute().actionGet(); - Map results = response.getAggregations().asMap(); - StringTerms topTags = (StringTerms) results.get("top_tags"); + final Map results = response.getAggregations().asMap(); + final StringTerms topTags = (StringTerms) results.get("top_tags"); - List keys = topTags.getBuckets().stream().map(b -> b.getKey()).collect(toList()); + final List keys = topTags.getBuckets().stream().map(b -> b.getKeyAsString()).collect(toList()); assertEquals(asList("elasticsearch", "spring data", "search engines", "tutorial"), keys); } @Test public void givenNotExactPhrase_whenUseSlop_thenQueryMatches() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1)) - .build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1)).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); } @Test public void givenPhraseWithType_whenUseFuzziness_thenQueryMatches() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title", "spring date elasticserch") - .operator(AND) - .fuzziness(Fuzziness.ONE) - .prefixLength(3)) - .build(); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "spring date elasticserch").operator(AND).fuzziness(Fuzziness.ONE).prefixLength(3)).build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); } @Test public void givenMultimatchQuery_whenDoSearch_thenAllProvidedFieldsMatch() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(multiMatchQuery("tutorial") - .field("title") - .field("tags") - .type(MultiMatchQueryBuilder.Type.BEST_FIELDS)) - .build(); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(multiMatchQuery("tutorial").field("title").field("tags").type(MultiMatchQueryBuilder.Type.BEST_FIELDS)).build(); - List
articles = elasticsearchTemplate - .queryForList(searchQuery, Article.class); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(2, articles.size()); } } diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchTest.java index 7b48772d3f..e10b5f48d7 100644 --- a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchTest.java +++ b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchTest.java @@ -1,9 +1,15 @@ package com.baeldung.spring.data.es; -import com.baeldung.spring.data.es.config.Config; -import com.baeldung.spring.data.es.model.Article; -import com.baeldung.spring.data.es.model.Author; -import com.baeldung.spring.data.es.service.ArticleService; +import static java.util.Arrays.asList; +import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND; +import static org.elasticsearch.index.query.QueryBuilders.fuzzyQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.index.query.QueryBuilders.regexpQuery; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,17 +23,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; -import java.util.List; - -import static java.util.Arrays.asList; -import static org.elasticsearch.index.query.FilterBuilders.regexpFilter; -import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND; -import static org.elasticsearch.index.query.QueryBuilders.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import com.baeldung.spring.data.es.config.Config; +import com.baeldung.spring.data.es.model.Article; +import com.baeldung.spring.data.es.model.Author; +import com.baeldung.spring.data.es.service.ArticleService; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {Config.class}, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { Config.class }, loader = AnnotationConfigContextLoader.class) public class ElasticSearchTest { @Autowired @@ -59,8 +61,7 @@ public class ElasticSearchTest { @Test public void givenArticleService_whenSaveArticle_thenIdIsAssigned() { - List authors = asList( - new Author("John Smith"), johnDoe); + final List authors = asList(new Author("John Smith"), johnDoe); Article article = new Article("Making Search Elastic"); article.setAuthors(authors); @@ -72,39 +73,34 @@ public class ElasticSearchTest { @Test public void givenPersistedArticles_whenSearchByAuthorsName_thenRightFound() { - Page
articleByAuthorName = articleService.findByAuthorName(johnSmith.getName(), new PageRequest(0, 10)); + final Page
articleByAuthorName = articleService.findByAuthorName(johnSmith.getName(), new PageRequest(0, 10)); assertEquals(2L, articleByAuthorName.getTotalElements()); } @Test public void givenCustomQuery_whenSearchByAuthorsName_thenArticleIsFound() { - Page
articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10)); + final Page
articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10)); assertEquals(3L, articleByAuthorName.getTotalElements()); } - @Test public void givenPersistedArticles_whenUseRegexQuery_thenRightArticlesFound() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withFilter(regexpFilter("title", ".*data.*")) - .build(); - List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(regexpQuery("title", ".*data.*")).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); } @Test public void givenSavedDoc_whenTitleUpdated_thenCouldFindByUpdatedTitle() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(fuzzyQuery("title", "serch")) - .build(); - List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(fuzzyQuery("title", "serch")).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); - Article article = articles.get(0); + final Article article = articles.get(0); final String newTitle = "Getting started with Search Engines"; article.setTitle(newTitle); articleService.save(article); @@ -117,10 +113,8 @@ public class ElasticSearchTest { final String articleTitle = "Spring Data Elasticsearch"; - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%")) - .build(); - List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%")).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); final long count = articleService.count(); @@ -131,10 +125,8 @@ public class ElasticSearchTest { @Test public void givenSavedDoc_whenOneTermMatches_thenFindByTitle() { - SearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(matchQuery("title", "Search engines").operator(AND)) - .build(); - List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); + final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND)).build(); + final List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); assertEquals(1, articles.size()); } } diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index 2944f53337..6d492863b4 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -213,13 +213,13 @@ io.springfox springfox-swagger2 - ${springfox.version} + ${springfox-swagger.version} io.springfox springfox-swagger-ui - ${springfox.version} + ${springfox-swagger.version} @@ -309,7 +309,6 @@ 1.1.0.Final 1.2 2.2.2 - 2.2.2 19.0 @@ -322,8 +321,7 @@ 2.9.0 - 2.2.2 - 2.2.2 + 2.4.0 4.4.1 4.5 diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java index 23c8155491..3302482f48 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java @@ -44,7 +44,7 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { .authorizeRequests() .antMatchers("/api/csrfAttacker*").permitAll() .antMatchers("/api/customer/**").permitAll() - .antMatchers("/api/**").authenticated() + .antMatchers("/api/foos/**").authenticated() .and() .formLogin() .successHandler(authenticationSuccessHandler) diff --git a/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java b/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java new file mode 100644 index 0000000000..792b3e28ce --- /dev/null +++ b/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java @@ -0,0 +1,20 @@ +package org.baeldung.web; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.jayway.restassured.RestAssured; +import com.jayway.restassured.response.Response; + +public class SwaggerLiveTest { + private static final String URL_PREFIX = "http://localhost:8080/spring-security-rest/api"; + + @Test + public void whenVerifySpringFoxIsWorking_thenOK() { + final Response response = RestAssured.get(URL_PREFIX + "/v2/api-docs"); + assertEquals(200, response.statusCode()); + System.out.println(response.asString()); + + } +}