Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-614
This commit is contained in:
commit
350765edfc
|
@ -0,0 +1,81 @@
|
||||||
|
package com.baeldung.java9.language.stream;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class CollectorImprovementTest {
|
||||||
|
private static class Blog {
|
||||||
|
private String authorName;
|
||||||
|
private List<String> comments;
|
||||||
|
|
||||||
|
public Blog(String authorName) {
|
||||||
|
this.authorName = authorName;
|
||||||
|
this.comments = new LinkedList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorName() {
|
||||||
|
return this.authorName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getComments() {
|
||||||
|
return new LinkedList<String>(this.comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComment(String comment) {
|
||||||
|
this.comments.add(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFiltering() {
|
||||||
|
List<Integer> numbers = List.of(1, 2, 3, 5, 5);
|
||||||
|
|
||||||
|
Map<Integer, Long> result = numbers.stream()
|
||||||
|
.filter(val -> val > 3).collect(Collectors.groupingBy(
|
||||||
|
Function.identity(), Collectors.counting()));
|
||||||
|
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
|
||||||
|
result = numbers.stream().collect(Collectors.groupingBy(
|
||||||
|
Function.identity(), Collectors.filtering(val -> val > 3,
|
||||||
|
Collectors.counting())));
|
||||||
|
|
||||||
|
assertEquals(4, result.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFlatMapping() {
|
||||||
|
Blog blog1 = new CollectorImprovementTest.Blog("1");
|
||||||
|
blog1.addComment("Nice");
|
||||||
|
blog1.addComment("Very Nice");
|
||||||
|
Blog blog2 = new CollectorImprovementTest.Blog("2");
|
||||||
|
blog2.addComment("Disappointing");
|
||||||
|
blog2.addComment("Ok");
|
||||||
|
blog2.addComment("Could be better");
|
||||||
|
List<Blog> blogs = List.of(blog1, blog2);
|
||||||
|
|
||||||
|
Map<String, List<List<String>>> authorComments1 =
|
||||||
|
blogs.stream().collect(Collectors.groupingBy(
|
||||||
|
Blog::getAuthorName, Collectors.mapping(
|
||||||
|
Blog::getComments, Collectors.toList())));
|
||||||
|
|
||||||
|
assertEquals(2, authorComments1.size());
|
||||||
|
assertEquals(2, authorComments1.get("1").get(0).size());
|
||||||
|
assertEquals(3, authorComments1.get("2").get(0).size());
|
||||||
|
|
||||||
|
Map<String, List<String>> authorComments2 =
|
||||||
|
blogs.stream().collect(Collectors.groupingBy(
|
||||||
|
Blog::getAuthorName, Collectors.flatMapping(
|
||||||
|
blog -> blog.getComments().stream(),
|
||||||
|
Collectors.toList())));
|
||||||
|
|
||||||
|
assertEquals(2, authorComments2.size());
|
||||||
|
assertEquals(2, authorComments2.get("1").size());
|
||||||
|
assertEquals(3, authorComments2.get("2").size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,3 +53,4 @@
|
||||||
- [Calculate the Size of a File in Java](http://www.baeldung.com/java-file-size)
|
- [Calculate the Size of a File in Java](http://www.baeldung.com/java-file-size)
|
||||||
- [The Basics of Java Generics](http://www.baeldung.com/java-generics)
|
- [The Basics of Java Generics](http://www.baeldung.com/java-generics)
|
||||||
- [The Traveling Salesman Problem in Java](http://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)
|
- [The Traveling Salesman Problem in Java](http://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)
|
||||||
|
- [How to Create an Executable JAR with Maven](http://www.baeldung.com/executable-jar-with-maven)
|
||||||
|
|
|
@ -64,11 +64,6 @@
|
||||||
<version>${grep4j.version}</version>
|
<version>${grep4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lmax</groupId>
|
|
||||||
<artifactId>disruptor</artifactId>
|
|
||||||
<version>${disruptor.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- web -->
|
<!-- web -->
|
||||||
|
|
||||||
<!-- marshalling -->
|
<!-- marshalling -->
|
||||||
|
@ -369,7 +364,6 @@
|
||||||
<unix4j.version>0.4</unix4j.version>
|
<unix4j.version>0.4</unix4j.version>
|
||||||
<grep4j.version>1.8.7</grep4j.version>
|
<grep4j.version>1.8.7</grep4j.version>
|
||||||
<lombok.version>1.16.12</lombok.version>
|
<lombok.version>1.16.12</lombok.version>
|
||||||
<disruptor.version>3.3.6</disruptor.version>
|
|
||||||
|
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<org.hamcrest.version>1.3</org.hamcrest.version>
|
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.concurrent.countdownlatch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
public class BrokenWorker implements Runnable {
|
||||||
|
private final List<String> outputScraper;
|
||||||
|
private final CountDownLatch countDownLatch;
|
||||||
|
|
||||||
|
public BrokenWorker(final List<String> outputScraper, final CountDownLatch countDownLatch) {
|
||||||
|
this.outputScraper = outputScraper;
|
||||||
|
this.countDownLatch = countDownLatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (true) {
|
||||||
|
throw new RuntimeException("Oh dear");
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
|
outputScraper.add("Counted down");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.concurrent.countdownlatch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
public class WaitingWorker implements Runnable {
|
||||||
|
|
||||||
|
private final List<String> outputScraper;
|
||||||
|
private final CountDownLatch readyThreadCounter;
|
||||||
|
private final CountDownLatch callingThreadBlocker;
|
||||||
|
private final CountDownLatch completedThreadCounter;
|
||||||
|
|
||||||
|
public WaitingWorker(final List<String> outputScraper,
|
||||||
|
final CountDownLatch readyThreadCounter,
|
||||||
|
final CountDownLatch callingThreadBlocker,
|
||||||
|
CountDownLatch completedThreadCounter) {
|
||||||
|
|
||||||
|
this.outputScraper = outputScraper;
|
||||||
|
this.readyThreadCounter = readyThreadCounter;
|
||||||
|
this.callingThreadBlocker = callingThreadBlocker;
|
||||||
|
this.completedThreadCounter = completedThreadCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Mark this thread as read / started
|
||||||
|
readyThreadCounter.countDown();
|
||||||
|
try {
|
||||||
|
callingThreadBlocker.await();
|
||||||
|
outputScraper.add("Counted down");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
completedThreadCounter.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.concurrent.countdownlatch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
public class Worker implements Runnable {
|
||||||
|
private final List<String> outputScraper;
|
||||||
|
private final CountDownLatch countDownLatch;
|
||||||
|
|
||||||
|
public Worker(final List<String> outputScraper, final CountDownLatch countDownLatch) {
|
||||||
|
this.outputScraper = outputScraper;
|
||||||
|
this.countDownLatch = countDownLatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Do some work
|
||||||
|
System.out.println("Doing some logic");
|
||||||
|
countDownLatch.countDown();
|
||||||
|
outputScraper.add("Counted down");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.baeldung.concurrent.countdownlatch;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class CountdownLatchExampleTest {
|
||||||
|
@Test
|
||||||
|
public void whenParallelProcessing_thenMainThreadWillBlockUntilCompletion() throws InterruptedException {
|
||||||
|
// Given
|
||||||
|
List<String> outputScraper = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
CountDownLatch countDownLatch = new CountDownLatch(5);
|
||||||
|
List<Thread> workers = Stream
|
||||||
|
.generate(() -> new Thread(new Worker(outputScraper, countDownLatch)))
|
||||||
|
.limit(5)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
// When
|
||||||
|
workers.forEach(Thread::start);
|
||||||
|
countDownLatch.await(); // Block until workers finish
|
||||||
|
outputScraper.add("Latch released");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
outputScraper.forEach(Object::toString);
|
||||||
|
assertThat(outputScraper)
|
||||||
|
.containsExactly(
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Latch released"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFailingToParallelProcess_thenMainThreadShouldTimeout() throws InterruptedException {
|
||||||
|
// Given
|
||||||
|
List<String> outputScraper = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
CountDownLatch countDownLatch = new CountDownLatch(5);
|
||||||
|
List<Thread> workers = Stream
|
||||||
|
.generate(() -> new Thread(new BrokenWorker(outputScraper, countDownLatch)))
|
||||||
|
.limit(5)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
// When
|
||||||
|
workers.forEach(Thread::start);
|
||||||
|
final boolean result = countDownLatch.await(3L, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDoingLotsOfThreadsInParallel_thenStartThemAtTheSameTime() throws InterruptedException {
|
||||||
|
// Given
|
||||||
|
List<String> outputScraper = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
CountDownLatch readyThreadCounter = new CountDownLatch(5);
|
||||||
|
CountDownLatch callingThreadBlocker = new CountDownLatch(1);
|
||||||
|
CountDownLatch completedThreadCounter = new CountDownLatch(5);
|
||||||
|
List<Thread> workers = Stream
|
||||||
|
.generate(() -> new Thread(new WaitingWorker(outputScraper, readyThreadCounter, callingThreadBlocker, completedThreadCounter)))
|
||||||
|
.limit(5)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
// When
|
||||||
|
workers.forEach(Thread::start);
|
||||||
|
readyThreadCounter.await(); // Block until workers start
|
||||||
|
outputScraper.add("Workers ready");
|
||||||
|
callingThreadBlocker.countDown(); // Start workers
|
||||||
|
completedThreadCounter.await(); // Block until workers finish
|
||||||
|
outputScraper.add("Workers complete");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
outputScraper.forEach(Object::toString);
|
||||||
|
assertThat(outputScraper)
|
||||||
|
.containsExactly(
|
||||||
|
"Workers ready",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Counted down",
|
||||||
|
"Workers complete"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,8 @@
|
||||||
package com.baeldung.guava;
|
package com.baeldung.guava;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import com.google.common.collect.BiMap;
|
import com.google.common.collect.BiMap;
|
||||||
import com.google.common.collect.EnumHashBiMap;
|
import com.google.common.collect.EnumHashBiMap;
|
||||||
|
@ -13,32 +11,32 @@ import com.google.common.collect.ImmutableBiMap;
|
||||||
|
|
||||||
public class GuavaBiMapTest {
|
public class GuavaBiMapTest {
|
||||||
@Test
|
@Test
|
||||||
public void whenQueryByValue_shouldReturnKey() {
|
public void whenQueryByValue_returnsKey() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
||||||
capitalCountryBiMap.put("New Delhi", "India");
|
capitalCountryBiMap.put("New Delhi", "India");
|
||||||
capitalCountryBiMap.put("Washingon, D.C.", "USA");
|
capitalCountryBiMap.put("Washingon, D.C.", "USA");
|
||||||
capitalCountryBiMap.put("Moscow", "Russia");
|
capitalCountryBiMap.put("Moscow", "Russia");
|
||||||
|
|
||||||
final String countryHeadName = capitalCountryBiMap.inverse().get("India");
|
final String countryCapitalName = capitalCountryBiMap.inverse().get("India");
|
||||||
|
|
||||||
assertEquals("New Delhi", countryHeadName);
|
assertEquals("New Delhi", countryCapitalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenCreateBiMapFromExistingMap_shouldReturnKey() {
|
public void whenCreateBiMapFromExistingMap_returnsKey() {
|
||||||
final Map<String, String> personCountryHeadMap = new HashMap<>();
|
final Map<String, String> capitalCountryMap = new HashMap<>();
|
||||||
personCountryHeadMap.put("New Delhi", "India");
|
capitalCountryMap.put("New Delhi", "India");
|
||||||
personCountryHeadMap.put("Washingon, D.C.", "USA");
|
capitalCountryMap.put("Washingon, D.C.", "USA");
|
||||||
personCountryHeadMap.put("Moscow", "Russia");
|
capitalCountryMap.put("Moscow", "Russia");
|
||||||
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create(personCountryHeadMap);
|
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create(capitalCountryMap);
|
||||||
|
|
||||||
final String countryHeadName = capitalCountryBiMap.inverse().get("India");
|
final String countryCapitalName = capitalCountryBiMap.inverse().get("India");
|
||||||
|
|
||||||
assertEquals("New Delhi", countryHeadName);
|
assertEquals("New Delhi", countryCapitalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenQueryByKey_shouldReturnValue() {
|
public void whenQueryByKey_returnsValue() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
||||||
|
|
||||||
capitalCountryBiMap.put("New Delhi", "India");
|
capitalCountryBiMap.put("New Delhi", "India");
|
||||||
|
@ -49,7 +47,7 @@ public class GuavaBiMapTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void whenSameValueIsBeingPresent_shouldThrowException() {
|
public void whenSameValueIsPresent_throwsException() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
||||||
|
|
||||||
capitalCountryBiMap.put("New Delhi", "India");
|
capitalCountryBiMap.put("New Delhi", "India");
|
||||||
|
@ -59,7 +57,7 @@ public class GuavaBiMapTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenSameValueIsBeingPresent_whenForcePutIsUsed_shouldCompleteSuccessfully() {
|
public void givenSameValueIsPresent_whenForcePut_completesSuccessfully() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
||||||
|
|
||||||
capitalCountryBiMap.put("New Delhi", "India");
|
capitalCountryBiMap.put("New Delhi", "India");
|
||||||
|
@ -72,7 +70,7 @@ public class GuavaBiMapTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSameKeyIsBeingPresent_shouldReplaceAlreadyPresent() {
|
public void whenSameKeyIsPresent_replacesAlreadyPresent() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
final BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
|
||||||
|
|
||||||
capitalCountryBiMap.put("New Delhi", "India");
|
capitalCountryBiMap.put("New Delhi", "India");
|
||||||
|
@ -84,21 +82,21 @@ public class GuavaBiMapTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingImmutableBiMap_shouldAllowPutSuccessfully() {
|
public void whenUsingImmutableBiMap_allowsPutSuccessfully() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
|
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
|
||||||
|
|
||||||
assertEquals("USA", capitalCountryBiMap.get("Washingon, D.C."));
|
assertEquals("USA", capitalCountryBiMap.get("Washingon, D.C."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
public void whenUsingImmutableBiMap_shouldNotAllowRemove() {
|
public void whenUsingImmutableBiMap_doesntAllowRemove() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
|
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
|
||||||
|
|
||||||
capitalCountryBiMap.remove("New Delhi");
|
capitalCountryBiMap.remove("New Delhi");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnsupportedOperationException.class)
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
public void whenUsingImmutableBiMap_shouldNotAllowPut() {
|
public void whenUsingImmutableBiMap_doesntAllowPut() {
|
||||||
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
|
final BiMap<String, String> capitalCountryBiMap = new ImmutableBiMap.Builder<String, String>().put("New Delhi", "India").put("Washingon, D.C.", "USA").put("Moscow", "Russia").build();
|
||||||
|
|
||||||
capitalCountryBiMap.put("New York", "USA");
|
capitalCountryBiMap.put("New York", "USA");
|
||||||
|
@ -109,7 +107,7 @@ public class GuavaBiMapTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingEnumAsKeyInMap_shouldReplaceAlreadyPresent() {
|
public void whenUsingEnumAsKeyInMap_replacesAlreadyPresent() {
|
||||||
final BiMap<Operation, String> operationStringBiMap = EnumHashBiMap.create(Operation.class);
|
final BiMap<Operation, String> operationStringBiMap = EnumHashBiMap.create(Operation.class);
|
||||||
|
|
||||||
operationStringBiMap.put(Operation.ADD, "Add");
|
operationStringBiMap.put(Operation.ADD, "Add");
|
||||||
|
|
|
@ -311,13 +311,7 @@ public class MapTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenTreeMap_whenOrdersEntriesByComparator_thenCorrect() {
|
public void givenTreeMap_whenOrdersEntriesByComparator_thenCorrect() {
|
||||||
TreeMap<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {
|
TreeMap<Integer, String> map = new TreeMap<>(Comparator.reverseOrder());
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(Integer o1, Integer o2) {
|
|
||||||
return o2 - o1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
map.put(3, "val");
|
map.put(3, "val");
|
||||||
map.put(2, "val");
|
map.put(2, "val");
|
||||||
map.put(1, "val");
|
map.put(1, "val");
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class Java8FindAnyFindFirstTest {
|
||||||
@Test
|
@Test
|
||||||
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
|
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
|
||||||
|
|
||||||
List<String> list = Arrays.asList("A","B","C","D");
|
List<String> list = Arrays.asList("A", "B", "C", "D");
|
||||||
|
|
||||||
Optional<String> result = list.stream().findAny();
|
Optional<String> result = list.stream().findAny();
|
||||||
|
|
||||||
|
@ -25,14 +25,27 @@ public class Java8FindAnyFindFirstTest {
|
||||||
assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
|
assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createParallelStream_whenFindAnyResultIsPresent_thenCorrect() throws Exception {
|
||||||
|
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
Optional<Integer> result = list
|
||||||
|
.stream()
|
||||||
|
.parallel()
|
||||||
|
.filter(num -> num < 4)
|
||||||
|
.findAny();
|
||||||
|
|
||||||
|
assertTrue(result.isPresent());
|
||||||
|
assertThat(result.get(), anyOf(is(1), is(2), is(3)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {
|
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {
|
||||||
|
|
||||||
List<String> list = Arrays.asList("A","B","C","D");
|
List<String> list = Arrays.asList("A", "B", "C", "D");
|
||||||
|
|
||||||
Optional<String> result = list.stream().findFirst();
|
Optional<String> result = list.stream().findFirst();
|
||||||
|
|
||||||
assertTrue(result.isPresent());
|
assertTrue(result.isPresent());
|
||||||
assertThat(result.get(),is("A"));
|
assertThat(result.get(), is("A"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>disruptor</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>disruptor</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.lmax</groupId>
|
||||||
|
<artifactId>disruptor</artifactId>
|
||||||
|
<version>${disruptor.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- logging -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${org.slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
|
<version>${org.slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>log4j-over-slf4j</artifactId>
|
||||||
|
<version>${org.slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-all</artifactId>
|
||||||
|
<version>1.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
<version>${org.hamcrest.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-library</artifactId>
|
||||||
|
<version>${org.hamcrest.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>disruptor</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-dependencies</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>libs/</classpathPrefix>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
|
<transformers>
|
||||||
|
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.jolira</groupId>
|
||||||
|
<artifactId>onejar-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
<attachToBuild>true</attachToBuild>
|
||||||
|
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>one-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>integration</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.mime>json</test.mime>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- logging -->
|
||||||
|
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||||
|
<logback.version>1.1.7</logback.version>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<disruptor.version>3.3.6</disruptor.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<mockito.version>1.10.19</mockito.version>
|
||||||
|
<testng.version>6.10</testng.version>
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
|
||||||
|
<!-- maven plugins -->
|
||||||
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,128 @@
|
||||||
|
package org.baeldung.guava;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.junit.Test;
|
||||||
|
import com.google.common.collect.ImmutableRangeMap;
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import com.google.common.collect.RangeMap;
|
||||||
|
import com.google.common.collect.TreeRangeMap;
|
||||||
|
|
||||||
|
public class GuavaRangeMapTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeMap_whenQueryWithinRange_returnsSucessfully() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = TreeRangeMap.create();
|
||||||
|
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(9, 15), "Executive Director");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(16, 30), "Managing Director");
|
||||||
|
|
||||||
|
assertEquals("Vice President", experienceRangeDesignationMap.get(6));
|
||||||
|
assertEquals("Executive Director", experienceRangeDesignationMap.get(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeMap_whenQueryOutsideRange_returnsNull() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = TreeRangeMap.create();
|
||||||
|
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(9, 15), "Executive Director");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(16, 30), "Managing Director");
|
||||||
|
|
||||||
|
assertNull(experienceRangeDesignationMap.get(31));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeMap_whenRemoveRangeIsCalled_removesSucessfully() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = TreeRangeMap.create();
|
||||||
|
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(9, 15), "Executive Director");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(16, 30), "Managing Director");
|
||||||
|
experienceRangeDesignationMap.remove(Range.closed(8, 15));
|
||||||
|
experienceRangeDesignationMap.remove(Range.closed(20, 26));
|
||||||
|
|
||||||
|
assertNull(experienceRangeDesignationMap.get(9));
|
||||||
|
assertEquals("Managing Director", experienceRangeDesignationMap.get(16));
|
||||||
|
assertEquals("Managing Director", experienceRangeDesignationMap.get(30));
|
||||||
|
assertNull(experienceRangeDesignationMap.get(25));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeMap_whenSpanIsCalled_returnsSucessfully() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = TreeRangeMap.create();
|
||||||
|
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(9, 15), "Executive Director");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(16, 30), "Managing Director");
|
||||||
|
final Range<Integer> experienceSpan = experienceRangeDesignationMap.span();
|
||||||
|
|
||||||
|
assertEquals(0, experienceSpan.lowerEndpoint().intValue());
|
||||||
|
assertEquals(30, experienceSpan.upperEndpoint().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeMap_whenGetEntryIsCalled_returnsEntrySucessfully() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = TreeRangeMap.create();
|
||||||
|
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(9, 15), "Executive Director");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(20, 30), "Managing Director");
|
||||||
|
final Map.Entry<Range<Integer>, String> experiencEntry = experienceRangeDesignationMap.getEntry(10);
|
||||||
|
|
||||||
|
assertEquals(Range.closed(9, 15), experiencEntry.getKey());
|
||||||
|
assertEquals("Executive Director", experiencEntry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeMap_whenSubRangeMapIsCalled_returnsSubRangeSucessfully() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = TreeRangeMap.create();
|
||||||
|
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(0, 2), "Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(3, 5), "Senior Associate");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(6, 8), "Vice President");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(8, 15), "Executive Director");
|
||||||
|
experienceRangeDesignationMap.put(Range.closed(16, 30), "Managing Director");
|
||||||
|
final RangeMap<Integer, String> experiencedSubRangeDesignationMap = experienceRangeDesignationMap.subRangeMap(Range.closed(4, 14));
|
||||||
|
|
||||||
|
assertNull(experiencedSubRangeDesignationMap.get(3));
|
||||||
|
assertEquals("Executive Director", experiencedSubRangeDesignationMap.get(14));
|
||||||
|
assertEquals("Vice President", experiencedSubRangeDesignationMap.get(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImmutableRangeMap_whenQueryWithinRange_returnsSucessfully() {
|
||||||
|
final RangeMap<Integer, String> experienceRangeDesignationMap = ImmutableRangeMap.<Integer, String> builder()
|
||||||
|
.put(Range.closed(0, 2), "Associate")
|
||||||
|
.put(Range.closed(3, 5), "Senior Associate")
|
||||||
|
.put(Range.closed(6, 8), "Vice President")
|
||||||
|
.put(Range.closed(9, 15), "Executive Director")
|
||||||
|
.put(Range.closed(16, 30), "Managing Director").build();
|
||||||
|
|
||||||
|
assertEquals("Vice President", experienceRangeDesignationMap.get(6));
|
||||||
|
assertEquals("Executive Director", experienceRangeDesignationMap.get(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void givenImmutableRangeMap_whenRangeOverlaps_ThrowsException() {
|
||||||
|
ImmutableRangeMap.<Integer, String> builder()
|
||||||
|
.put(Range.closed(0, 2), "Associate")
|
||||||
|
.put(Range.closed(3, 5), "Senior Associate")
|
||||||
|
.put(Range.closed(6, 8), "Vice President")
|
||||||
|
.put(Range.closed(8, 15), "Executive Director")
|
||||||
|
.put(Range.closed(16, 30), "Managing Director").build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
package org.baeldung.guava;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import org.junit.Test;
|
||||||
|
import com.google.common.collect.ImmutableRangeSet;
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import com.google.common.collect.RangeSet;
|
||||||
|
import com.google.common.collect.TreeRangeSet;
|
||||||
|
|
||||||
|
public class GuavaRangeSetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenQueryWithinRange_returnsSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 5));
|
||||||
|
numberRangeSet.add(Range.closed(6, 8));
|
||||||
|
|
||||||
|
assertTrue(numberRangeSet.contains(1));
|
||||||
|
assertFalse(numberRangeSet.contains(9));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenEnclosesWithinRange_returnsSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 10));
|
||||||
|
numberRangeSet.add(Range.closed(15, 18));
|
||||||
|
|
||||||
|
assertTrue(numberRangeSet.encloses(Range.closed(4, 5)));
|
||||||
|
assertFalse(numberRangeSet.encloses(Range.closed(4, 11)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenComplementIsCalled_returnsSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 5));
|
||||||
|
numberRangeSet.add(Range.closed(6, 8));
|
||||||
|
final RangeSet<Integer> numberRangeComplementSet = numberRangeSet.complement();
|
||||||
|
|
||||||
|
assertTrue(numberRangeComplementSet.contains(-1000));
|
||||||
|
assertFalse(numberRangeComplementSet.contains(2));
|
||||||
|
assertFalse(numberRangeComplementSet.contains(3));
|
||||||
|
assertTrue(numberRangeComplementSet.contains(1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenIntersectsWithinRange_returnsSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 10));
|
||||||
|
numberRangeSet.add(Range.closed(15, 18));
|
||||||
|
|
||||||
|
assertTrue(numberRangeSet.intersects(Range.closed(4, 17)));
|
||||||
|
assertFalse(numberRangeSet.intersects(Range.closed(19, 200)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenRemoveRangeIsCalled_removesSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 5));
|
||||||
|
numberRangeSet.add(Range.closed(6, 8));
|
||||||
|
numberRangeSet.add(Range.closed(9, 15));
|
||||||
|
numberRangeSet.remove(Range.closed(3, 5));
|
||||||
|
numberRangeSet.remove(Range.closed(7, 10));
|
||||||
|
|
||||||
|
assertTrue(numberRangeSet.contains(1));
|
||||||
|
assertFalse(numberRangeSet.contains(9));
|
||||||
|
assertTrue(numberRangeSet.contains(12));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenSpanIsCalled_returnsSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 5));
|
||||||
|
numberRangeSet.add(Range.closed(6, 8));
|
||||||
|
final Range<Integer> experienceSpan = numberRangeSet.span();
|
||||||
|
|
||||||
|
assertEquals(0, experienceSpan.lowerEndpoint().intValue());
|
||||||
|
assertEquals(8, experienceSpan.upperEndpoint().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRangeSet_whenSubRangeSetIsCalled_returnsSubRangeSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
|
||||||
|
|
||||||
|
numberRangeSet.add(Range.closed(0, 2));
|
||||||
|
numberRangeSet.add(Range.closed(3, 5));
|
||||||
|
numberRangeSet.add(Range.closed(6, 8));
|
||||||
|
final RangeSet<Integer> numberSubRangeSet = numberRangeSet.subRangeSet(Range.closed(4, 14));
|
||||||
|
|
||||||
|
assertFalse(numberSubRangeSet.contains(3));
|
||||||
|
assertFalse(numberSubRangeSet.contains(14));
|
||||||
|
assertTrue(numberSubRangeSet.contains(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImmutableRangeSet_whenQueryWithinRange_returnsSucessfully() {
|
||||||
|
final RangeSet<Integer> numberRangeSet = ImmutableRangeSet.<Integer> builder()
|
||||||
|
.add(Range.closed(0, 2))
|
||||||
|
.add(Range.closed(3, 5))
|
||||||
|
.add(Range.closed(6, 8)).build();
|
||||||
|
|
||||||
|
assertTrue(numberRangeSet.contains(6));
|
||||||
|
assertFalse(numberRangeSet.contains(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void givenImmutableRangeMap_whenRangeOverlaps_ThrowsException() {
|
||||||
|
ImmutableRangeSet.<Integer> builder()
|
||||||
|
.add(Range.closed(0, 2))
|
||||||
|
.add(Range.closed(3, 5))
|
||||||
|
.add(Range.closed(5, 8)).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,12 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<project
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>java-mongodb</artifactId>
|
<artifactId>java-mongodb</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
|
||||||
<junit.version>4.12</junit.version>
|
|
||||||
<mongo.version>3.4.1</mongo.version>
|
|
||||||
<flapdoodle.version>1.11</flapdoodle.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -41,4 +32,67 @@
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LongRunningUnitTest.java</exclude>
|
||||||
|
<exclude>**/*ManualTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<testFailureIgnore>true</testFailureIgnore>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>integration</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*ManualTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*IntegrationTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.mime>json</test.mime>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<mongo.version>3.4.1</mongo.version>
|
||||||
|
<flapdoodle.version>1.11</flapdoodle.version>
|
||||||
|
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -7,7 +7,7 @@ import com.mongodb.DBCursor;
|
||||||
import com.mongodb.MongoClient;
|
import com.mongodb.MongoClient;
|
||||||
|
|
||||||
public class MongoExample {
|
public class MongoExample {
|
||||||
public static void main( String[] args ) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
MongoClient mongoClient = new MongoClient("localhost", 27017);
|
MongoClient mongoClient = new MongoClient("localhost", 27017);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DB;
|
||||||
|
import com.mongodb.DBCollection;
|
||||||
|
import com.mongodb.DBCursor;
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
|
||||||
|
import de.flapdoodle.embedmongo.MongoDBRuntime;
|
||||||
|
import de.flapdoodle.embedmongo.MongodExecutable;
|
||||||
|
import de.flapdoodle.embedmongo.MongodProcess;
|
||||||
|
import de.flapdoodle.embedmongo.config.MongodConfig;
|
||||||
|
import de.flapdoodle.embedmongo.distribution.Version;
|
||||||
|
import de.flapdoodle.embedmongo.runtime.Network;
|
||||||
|
|
||||||
|
public class AppIntegrationTest {
|
||||||
|
|
||||||
|
private static final String DB_NAME = "myMongoDb";
|
||||||
|
private MongodExecutable mongodExe;
|
||||||
|
private MongodProcess mongod;
|
||||||
|
private Mongo mongo;
|
||||||
|
private DB db;
|
||||||
|
private DBCollection collection;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
// Creating Mongodbruntime instance
|
||||||
|
MongoDBRuntime runtime = MongoDBRuntime.getDefaultInstance();
|
||||||
|
|
||||||
|
// Creating MongodbExecutable
|
||||||
|
mongodExe = runtime.prepare(new MongodConfig(Version.V2_0_1, 12345, Network.localhostIsIPv6()));
|
||||||
|
|
||||||
|
// Starting Mongodb
|
||||||
|
mongod = mongodExe.start();
|
||||||
|
mongo = new Mongo("localhost", 12345);
|
||||||
|
|
||||||
|
// Creating DB
|
||||||
|
db = mongo.getDB(DB_NAME);
|
||||||
|
|
||||||
|
// Creating collection Object and adding values
|
||||||
|
collection = db.getCollection("customers");
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void teardown() throws Exception {
|
||||||
|
mongod.stop();
|
||||||
|
mongodExe.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddressPersistance() {
|
||||||
|
BasicDBObject contact = new BasicDBObject();
|
||||||
|
contact.put("name", "John");
|
||||||
|
contact.put("company", "Baeldung");
|
||||||
|
|
||||||
|
// Inserting document
|
||||||
|
collection.insert(contact);
|
||||||
|
DBCursor cursorDoc = collection.find();
|
||||||
|
BasicDBObject contact1 = new BasicDBObject();
|
||||||
|
while (cursorDoc.hasNext()) {
|
||||||
|
contact1 = (BasicDBObject) cursorDoc.next();
|
||||||
|
System.out.println(contact1);
|
||||||
|
}
|
||||||
|
assertEquals(contact1.get("name"), "John");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
package com.baeldung;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import com.mongodb.BasicDBObject;
|
|
||||||
import com.mongodb.DB;
|
|
||||||
import com.mongodb.DBCollection;
|
|
||||||
import com.mongodb.DBCursor;
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import de.flapdoodle.embedmongo.MongoDBRuntime;
|
|
||||||
import de.flapdoodle.embedmongo.MongodExecutable;
|
|
||||||
import de.flapdoodle.embedmongo.MongodProcess;
|
|
||||||
import de.flapdoodle.embedmongo.config.MongodConfig;
|
|
||||||
import de.flapdoodle.embedmongo.distribution.Version;
|
|
||||||
import de.flapdoodle.embedmongo.runtime.Network;
|
|
||||||
|
|
||||||
public class AppTest {
|
|
||||||
|
|
||||||
private static final String DB_NAME = "myMongoDb";
|
|
||||||
private MongodExecutable mongodExe;
|
|
||||||
private MongodProcess mongod;
|
|
||||||
private Mongo mongo;
|
|
||||||
private DB db;
|
|
||||||
private DBCollection collection;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() throws Exception {
|
|
||||||
|
|
||||||
// Creating Mongodbruntime instance
|
|
||||||
MongoDBRuntime runtime = MongoDBRuntime.getDefaultInstance();
|
|
||||||
|
|
||||||
// Creating MongodbExecutable
|
|
||||||
mongodExe = runtime.prepare(new MongodConfig(Version.V2_0_1, 12345,
|
|
||||||
Network.localhostIsIPv6()));
|
|
||||||
|
|
||||||
// Starting Mongodb
|
|
||||||
mongod = mongodExe.start();
|
|
||||||
mongo = new Mongo("localhost", 12345);
|
|
||||||
|
|
||||||
// Creating DB
|
|
||||||
db = mongo.getDB(DB_NAME);
|
|
||||||
|
|
||||||
// Creating collection Object and adding values
|
|
||||||
collection = db.getCollection("customers");
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void teardown() throws Exception {
|
|
||||||
mongod.stop();
|
|
||||||
mongodExe.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddressPersistance() {
|
|
||||||
|
|
||||||
BasicDBObject contact = new BasicDBObject();
|
|
||||||
contact.put("name", "John");
|
|
||||||
contact.put("company", "Baeldung");
|
|
||||||
|
|
||||||
// Inserting document
|
|
||||||
collection.insert(contact);
|
|
||||||
DBCursor cursorDoc = collection.find();
|
|
||||||
BasicDBObject contact1 = new BasicDBObject();
|
|
||||||
while (cursorDoc.hasNext()) {
|
|
||||||
contact1 = (BasicDBObject) cursorDoc.next();
|
|
||||||
System.out.println(contact1);
|
|
||||||
}
|
|
||||||
assertEquals(contact1.get("name"), "John");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +1,15 @@
|
||||||
package com.baeldung.metrics.core;
|
package com.baeldung.metrics.core;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import com.codahale.metrics.*;
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import com.codahale.metrics.*;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
public class MetricsTest {
|
public class MetricsTest {
|
||||||
@Test
|
@Test
|
||||||
|
@ -139,7 +138,7 @@ public class MetricsTest {
|
||||||
|
|
||||||
long elapsed1 = context1.stop();
|
long elapsed1 = context1.stop();
|
||||||
|
|
||||||
assertEquals(5000000000L, elapsed1, 1000000);
|
assertEquals(5000000000L, elapsed1, 10000000);
|
||||||
assertThat(timer.getCount(), equalTo(1L));
|
assertThat(timer.getCount(), equalTo(1L));
|
||||||
assertEquals(0.2, timer.getMeanRate(), 0.1);
|
assertEquals(0.2, timer.getMeanRate(), 0.1);
|
||||||
|
|
||||||
|
|
7
pom.xml
7
pom.xml
|
@ -44,6 +44,7 @@
|
||||||
<module>guava</module>
|
<module>guava</module>
|
||||||
<module>guava18</module>
|
<module>guava18</module>
|
||||||
<module>guava19</module>
|
<module>guava19</module>
|
||||||
|
<module>disruptor</module>
|
||||||
|
|
||||||
<module>handling-spring-static-resources</module>
|
<module>handling-spring-static-resources</module>
|
||||||
<module>hazelcast</module>
|
<module>hazelcast</module>
|
||||||
|
@ -94,6 +95,7 @@
|
||||||
<module>resteasy</module>
|
<module>resteasy</module>
|
||||||
|
|
||||||
<module>selenium-junit-testng</module>
|
<module>selenium-junit-testng</module>
|
||||||
|
<module>spark-java</module>
|
||||||
<module>spring-akka</module>
|
<module>spring-akka</module>
|
||||||
<module>spring-amqp</module>
|
<module>spring-amqp</module>
|
||||||
<module>spring-all</module>
|
<module>spring-all</module>
|
||||||
|
@ -174,12 +176,15 @@
|
||||||
|
|
||||||
<module>testing</module>
|
<module>testing</module>
|
||||||
|
|
||||||
|
<module>video-tutorials</module>
|
||||||
|
|
||||||
<module>wicket</module>
|
<module>wicket</module>
|
||||||
|
|
||||||
<module>xml</module>
|
<module>xml</module>
|
||||||
<module>xmlunit2</module>
|
<module>xmlunit2</module>
|
||||||
<module>xstream</module>
|
<module>xstream</module>
|
||||||
<module>java-mongodb</module>
|
|
||||||
|
<module>struts2</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,2 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Intro to Jedis – the Java Redis Client Library](http://www.baeldung.com/jedis-java-redis-client-library)
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>rest-with-spark-java</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>rest-with-spark-java</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sparkjava</groupId>
|
||||||
|
<artifactId>spark-core</artifactId>
|
||||||
|
<version>2.5.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-core</artifactId>
|
||||||
|
<version>2.8.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.8.6</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import static spark.Spark.after;
|
||||||
|
import static spark.Spark.before;
|
||||||
|
import static spark.Spark.delete;
|
||||||
|
import static spark.Spark.get;
|
||||||
|
import static spark.Spark.post;
|
||||||
|
import static spark.Spark.port;
|
||||||
|
|
||||||
|
import com.baeldung.domain.Book;
|
||||||
|
import com.baeldung.service.LibraryService;
|
||||||
|
|
||||||
|
public class Router {
|
||||||
|
|
||||||
|
public static void main( String[] args ){
|
||||||
|
|
||||||
|
port(8080);
|
||||||
|
|
||||||
|
before((request, response) -> {
|
||||||
|
|
||||||
|
//do some filtering stuff
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
after((request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
});
|
||||||
|
|
||||||
|
get("ListOfBooks", (request, response) -> {
|
||||||
|
return LibraryService.view();
|
||||||
|
});
|
||||||
|
|
||||||
|
get("SearchBook/:title", (request, response) -> {
|
||||||
|
return LibraryService.view(request.params("title"));
|
||||||
|
});
|
||||||
|
|
||||||
|
post("AddBook/:title/:author/:publisher", (request, response) -> {
|
||||||
|
Book book = new Book();
|
||||||
|
book.setTitle(request.params("title"));
|
||||||
|
book.setAuthor(request.params("author"));
|
||||||
|
book.setPublisher(request.params("publisher"));
|
||||||
|
return LibraryService.add(book);
|
||||||
|
});
|
||||||
|
|
||||||
|
delete("DeleteBook/:title", (request, response) -> {
|
||||||
|
return LibraryService.delete(request.params("title"));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.domain;
|
||||||
|
|
||||||
|
public class Book {
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private String author;
|
||||||
|
private String publisher;
|
||||||
|
|
||||||
|
public Book() {}
|
||||||
|
|
||||||
|
public Book(String title, String author, String publisher) {
|
||||||
|
super();
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.publisher = publisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(String author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
public String getPublisher() {
|
||||||
|
return publisher;
|
||||||
|
}
|
||||||
|
public void setPublisher(String publisher) {
|
||||||
|
this.publisher = publisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canEqual(Object other) {
|
||||||
|
return other instanceof Book;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof Book)) return false;
|
||||||
|
Book other = (Book) o;
|
||||||
|
if (!other.canEqual((Object)this)) return false;
|
||||||
|
if (this.getTitle() == null ? other.getTitle() != null : !this.getTitle().equals(other.getTitle())) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.baeldung.domain.Book;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||||
|
|
||||||
|
public class LibraryService {
|
||||||
|
|
||||||
|
private static ObjectWriter mapper = new ObjectMapper().writer().withDefaultPrettyPrinter();
|
||||||
|
private static Map<String, Book> library = new HashMap<String,Book>();
|
||||||
|
|
||||||
|
public static String view() throws JsonProcessingException {
|
||||||
|
List<Book> books = new ArrayList<Book>();
|
||||||
|
library.forEach((key, value) -> {
|
||||||
|
books.add(value);
|
||||||
|
});
|
||||||
|
return mapper.writeValueAsString(books);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String view(String title) throws JsonProcessingException {
|
||||||
|
return mapper.writeValueAsString(library.get(title));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String add(Book book) throws JsonProcessingException {
|
||||||
|
library.put(book.getTitle(), book);
|
||||||
|
return mapper.writeValueAsString(book);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String delete(String title) throws JsonProcessingException {
|
||||||
|
Book deletedBook = library.remove(title);
|
||||||
|
return mapper.writeValueAsString(deletedBook);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.domain.Book;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
public class AppTest extends TestCase {
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
public AppTest( String testName ) {
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testApp() throws IOException, ClassNotFoundException {
|
||||||
|
|
||||||
|
URL url;
|
||||||
|
HttpURLConnection conn;
|
||||||
|
BufferedReader br;
|
||||||
|
String output;
|
||||||
|
StringBuffer resp;
|
||||||
|
Book book;
|
||||||
|
Book temp;
|
||||||
|
|
||||||
|
url = new URL("http://localhost:8080/AddBook/Odessy/YannMartel/GreenLeaves");
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.getContent();
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
(conn.getInputStream())));
|
||||||
|
resp = new StringBuffer();
|
||||||
|
|
||||||
|
while ((output = br.readLine()) != null) {
|
||||||
|
resp.append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
book = mapper.readValue(resp.toString(), Book.class);
|
||||||
|
temp = new Book("Odessy","YannMartel","GreenLeaves");
|
||||||
|
|
||||||
|
assertEquals(book, temp);
|
||||||
|
|
||||||
|
url = new URL("http://localhost:8080/AddBook/Twilight/StephenieMeyer/LittleBrown");
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
(conn.getInputStream())));
|
||||||
|
resp = new StringBuffer();
|
||||||
|
|
||||||
|
while ((output = br.readLine()) != null) {
|
||||||
|
resp.append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
book = mapper.readValue(resp.toString(), Book.class);
|
||||||
|
temp = new Book("Twilight","StephenieMeyer","LittleBrown");
|
||||||
|
|
||||||
|
assertEquals(book, temp);
|
||||||
|
|
||||||
|
url = new URL("http://localhost:8080/ListOfBooks");
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
(conn.getInputStream())));
|
||||||
|
resp = new StringBuffer();
|
||||||
|
|
||||||
|
while ((output = br.readLine()) != null) {
|
||||||
|
resp.append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Book> books = new ArrayList<Book>();
|
||||||
|
|
||||||
|
books.add(new Book("Odessy","YannMartel","GreenLeaves"));
|
||||||
|
books.add(new Book("Twilight","StephenieMeyer","LittleBrown"));
|
||||||
|
|
||||||
|
List<Book> listOfBooks = mapper.readValue(resp.toString(), new TypeReference<List<Book>>(){});
|
||||||
|
|
||||||
|
assertEquals(books, listOfBooks);
|
||||||
|
|
||||||
|
url = new URL("http://localhost:8080/SearchBook/Twilight");
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
(conn.getInputStream())));
|
||||||
|
resp = new StringBuffer();
|
||||||
|
|
||||||
|
while ((output = br.readLine()) != null) {
|
||||||
|
resp.append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
book = mapper.readValue(resp.toString(), Book.class);
|
||||||
|
temp = new Book("Twilight","StephenieMeyer","LittleBrown");
|
||||||
|
|
||||||
|
assertEquals(book, temp);
|
||||||
|
|
||||||
|
url = new URL("http://localhost:8080/DeleteBook/Twilight");
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("DELETE");
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
(conn.getInputStream())));
|
||||||
|
resp = new StringBuffer();
|
||||||
|
|
||||||
|
while ((output = br.readLine()) != null) {
|
||||||
|
resp.append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
book = mapper.readValue(resp.toString(), Book.class);
|
||||||
|
temp = new Book("Twilight","StephenieMeyer","LittleBrown");
|
||||||
|
|
||||||
|
assertEquals(book, temp);
|
||||||
|
|
||||||
|
url = new URL("http://localhost:8080/ListOfBooks");
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
(conn.getInputStream())));
|
||||||
|
resp = new StringBuffer();
|
||||||
|
|
||||||
|
while ((output = br.readLine()) != null) {
|
||||||
|
resp.append(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
books = new ArrayList<Book>();
|
||||||
|
|
||||||
|
books.add(new Book("Odessy","YannMartel","GreenLeaves"));
|
||||||
|
listOfBooks = mapper.readValue(resp.toString(), new TypeReference<List<Book>>(){});
|
||||||
|
|
||||||
|
assertEquals(books, listOfBooks);
|
||||||
|
|
||||||
|
conn.disconnect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spark-java</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>spark-java</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sparkjava</groupId>
|
||||||
|
<artifactId>spark-core</artifactId>
|
||||||
|
<version>2.5.4</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
import static spark.Spark.*;
|
||||||
|
|
||||||
|
public class HelloWorldService {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
get("/hello", (req,res)->"Hello, Baeldung");
|
||||||
|
|
||||||
|
get("/hello/:name", (req,res)->{
|
||||||
|
return "Hello: "+ req.params(":name");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
import static spark.Spark.delete;
|
||||||
|
import static spark.Spark.get;
|
||||||
|
import static spark.Spark.options;
|
||||||
|
import static spark.Spark.post;
|
||||||
|
import static spark.Spark.put;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class SparkRestExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final UserService userService = new UserServiceMapImpl();
|
||||||
|
|
||||||
|
post("/users", (request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
|
||||||
|
User user = new Gson().fromJson(request.body(), User.class);
|
||||||
|
userService.addUser(user);
|
||||||
|
|
||||||
|
return new Gson().toJson(new StandardResponse(StatusResponse.SUCCESS));
|
||||||
|
});
|
||||||
|
|
||||||
|
get("/users", (request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
|
||||||
|
return new Gson().toJson(
|
||||||
|
new StandardResponse(StatusResponse.SUCCESS,new Gson()
|
||||||
|
.toJsonTree(userService.getUsers())));
|
||||||
|
});
|
||||||
|
|
||||||
|
get("/users/:id", (request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
|
||||||
|
return new Gson().toJson(
|
||||||
|
new StandardResponse(StatusResponse.SUCCESS,new Gson()
|
||||||
|
.toJsonTree(userService.getUser(request.params(":id")))));
|
||||||
|
});
|
||||||
|
|
||||||
|
put("/users/:id", (request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
|
||||||
|
User toEdit = new Gson().fromJson(request.body(), User.class);
|
||||||
|
User editedUser = userService.editUser(toEdit);
|
||||||
|
|
||||||
|
if (editedUser != null) {
|
||||||
|
return new Gson().toJson(
|
||||||
|
new StandardResponse(StatusResponse.SUCCESS,new Gson()
|
||||||
|
.toJsonTree(editedUser)));
|
||||||
|
}else {
|
||||||
|
return new Gson().toJson(
|
||||||
|
new StandardResponse(StatusResponse.ERROR,new Gson()
|
||||||
|
.toJson("User not found or error in edit")));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
delete("/users/:id", (request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
|
||||||
|
userService.deleteUser(request.params(":id"));
|
||||||
|
return new Gson().toJson(
|
||||||
|
new StandardResponse(StatusResponse.SUCCESS, "user deleted"));
|
||||||
|
});
|
||||||
|
|
||||||
|
options("/users/:id", (request, response) -> {
|
||||||
|
response.type("application/json");
|
||||||
|
|
||||||
|
return new Gson().toJson(
|
||||||
|
new StandardResponse(StatusResponse.SUCCESS,
|
||||||
|
(userService.userExist(
|
||||||
|
request.params(":id"))) ? "User exists" : "User does not exists" ));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
|
public class StandardResponse {
|
||||||
|
private StatusResponse status;
|
||||||
|
private String message;
|
||||||
|
private JsonElement data;
|
||||||
|
|
||||||
|
public StandardResponse(StatusResponse status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardResponse(StatusResponse status, String message) {
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardResponse(StatusResponse status, JsonElement data) {
|
||||||
|
this.status = status;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusResponse getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusResponse status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(JsonElement data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
public enum StatusResponse {
|
||||||
|
SUCCESS ("Success"),
|
||||||
|
ERROR ("Error");
|
||||||
|
|
||||||
|
final private String status;
|
||||||
|
|
||||||
|
StatusResponse(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
class User {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
public User(String id, String firstName, String lastName, String email) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new StringBuffer().append(getEmail()).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
public class UserException extends Exception{
|
||||||
|
|
||||||
|
public UserException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface UserService {
|
||||||
|
public void addUser (User user) ;
|
||||||
|
public Collection<User> getUsers () ;
|
||||||
|
public User getUser (String id) ;
|
||||||
|
public User editUser (User user) throws UserException;
|
||||||
|
public void deleteUser (String id) ;
|
||||||
|
public boolean userExist (String id);
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.baeldung.sparkjava;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class UserServiceMapImpl implements UserService{
|
||||||
|
private HashMap<String, User> userMap;
|
||||||
|
|
||||||
|
public UserServiceMapImpl() {
|
||||||
|
userMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addUser (User user) {
|
||||||
|
userMap.put(user.getId(), user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<User> getUsers () {
|
||||||
|
return userMap.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUser (String id) {
|
||||||
|
return userMap.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User editUser (User forEdit) throws UserException{
|
||||||
|
try{
|
||||||
|
if (forEdit.getId() == null)
|
||||||
|
throw new UserException("ID cannot be blank");
|
||||||
|
|
||||||
|
User toEdit = userMap.get(forEdit.getId());
|
||||||
|
|
||||||
|
if (toEdit == null )
|
||||||
|
throw new UserException("User not found");
|
||||||
|
|
||||||
|
if (forEdit.getEmail()!=null) {
|
||||||
|
toEdit.setEmail(forEdit.getEmail());
|
||||||
|
}
|
||||||
|
if (forEdit.getFirstName()!=null) {
|
||||||
|
toEdit.setFirstName(forEdit.getFirstName());
|
||||||
|
}
|
||||||
|
if (forEdit.getLastName()!=null) {
|
||||||
|
toEdit.setLastName(forEdit.getLastName());
|
||||||
|
}
|
||||||
|
if (forEdit.getId()!=null) {
|
||||||
|
toEdit.setId(forEdit.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return toEdit;
|
||||||
|
}catch (Exception ex) {
|
||||||
|
throw new UserException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteUser (String id) {
|
||||||
|
userMap.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean userExist (String id) {
|
||||||
|
return userMap.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>MyFirstSpringBoot</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
|
||||||
<version>1.4.3.RELEASE</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<name>MyFirstSpringBoot</name>
|
|
||||||
<url>http://maven.apache.org</url>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung;
|
package com.baeldung.intro;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.controller;
|
package com.baeldung.intro.controller;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung;
|
package com.baeldung.intro;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
|
@ -0,0 +1,20 @@
|
||||||
|
spring.application.name=resource
|
||||||
|
#server.port=0
|
||||||
|
|
||||||
|
#### cloud
|
||||||
|
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka}
|
||||||
|
eureka.instance.preferIpAddress=true
|
||||||
|
|
||||||
|
#### persistence
|
||||||
|
spring.datasource.driver-class-name=org.h2.Driver
|
||||||
|
spring.datasource.url=jdbc:h2:mem:cloud_rest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=
|
||||||
|
|
||||||
|
#### security
|
||||||
|
security.basic.enabled=true
|
||||||
|
security.basic.path=/**
|
||||||
|
security.user.name=user
|
||||||
|
security.user.password=userPass
|
||||||
|
security.user.role=USER
|
||||||
|
security.sessions=always
|
|
@ -0,0 +1,16 @@
|
||||||
|
spring.application.name=spring-cloud-rest-server
|
||||||
|
server.port=8761
|
||||||
|
|
||||||
|
#### cloud
|
||||||
|
eureka.instance.hostname=localhost
|
||||||
|
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka}
|
||||||
|
eureka.client.registerWithEureka=false
|
||||||
|
eureka.client.fetchRegistry=false
|
||||||
|
|
||||||
|
#### security
|
||||||
|
security.basic.enabled=true
|
||||||
|
security.basic.path=/**
|
||||||
|
security.user.name=system
|
||||||
|
security.user.password=systemPass
|
||||||
|
security.user.role=ADMIN
|
||||||
|
security.sessions=always
|
|
@ -7,8 +7,10 @@
|
||||||
<artifactId>spring-cloud-rest</artifactId>
|
<artifactId>spring-cloud-rest</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
<modules>
|
<modules>
|
||||||
|
<module>spring-cloud-rest-config</module>
|
||||||
<module>spring-cloud-rest-server</module>
|
<module>spring-cloud-rest-server</module>
|
||||||
<module>spring-cloud-rest-client</module>
|
<module>spring-cloud-rest-client-1</module>
|
||||||
|
<module>spring-cloud-rest-client-2</module>
|
||||||
</modules>
|
</modules>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.baeldung</groupId>
|
||||||
|
<artifactId>spring-cloud-rest-client-1</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-cloud-rest-client-1</name>
|
||||||
|
<description>Client Service for books</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.4.3.RELEASE</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<rest-assured.version>3.0.1</rest-assured.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>Camden.SR4</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||||
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
|
@EnableRedisHttpSession
|
||||||
|
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.baeldung.persistence.dao;
|
||||||
|
|
||||||
|
import org.baeldung.persistence.model.Book;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
||||||
|
|
||||||
|
@RepositoryRestResource(collectionResourceRel = "books", path = "books")
|
||||||
|
public interface BookRepository extends CrudRepository<Book, Long> {
|
||||||
|
Page<Book> findByTitle(@Param("title") String title, Pageable pageable);
|
||||||
|
}
|
|
@ -12,12 +12,9 @@ public class Book {
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false, unique = true)
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
private String isbn;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String author;
|
private String author;
|
||||||
|
|
||||||
|
@ -27,10 +24,9 @@ public class Book {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Book(String title, String isbn, String author) {
|
public Book(String title, String author) {
|
||||||
super();
|
super();
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.isbn = isbn;
|
|
||||||
this.author = author;
|
this.author = author;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,14 +48,6 @@ public class Book {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIsbn() {
|
|
||||||
return isbn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsbn(String isbn) {
|
|
||||||
this.isbn = isbn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthor() {
|
public String getAuthor() {
|
||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +64,6 @@ public class Book {
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = (prime * result) + ((author == null) ? 0 : author.hashCode());
|
result = (prime * result) + ((author == null) ? 0 : author.hashCode());
|
||||||
result = (prime * result) + (int) (id ^ (id >>> 32));
|
result = (prime * result) + (int) (id ^ (id >>> 32));
|
||||||
result = (prime * result) + ((isbn == null) ? 0 : isbn.hashCode());
|
|
||||||
result = (prime * result) + ((title == null) ? 0 : title.hashCode());
|
result = (prime * result) + ((title == null) ? 0 : title.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -103,13 +90,7 @@ public class Book {
|
||||||
if (id != other.id) {
|
if (id != other.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isbn == null) {
|
|
||||||
if (other.isbn != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!isbn.equals(other.isbn)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (title == null) {
|
if (title == null) {
|
||||||
if (other.title != null) {
|
if (other.title != null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -127,8 +108,6 @@ public class Book {
|
||||||
.append(id)
|
.append(id)
|
||||||
.append(", title=")
|
.append(", title=")
|
||||||
.append(title)
|
.append(title)
|
||||||
.append(", isbn=")
|
|
||||||
.append(isbn)
|
|
||||||
.append(", author=")
|
.append(", author=")
|
||||||
.append(author)
|
.append(author)
|
||||||
.append("]");
|
.append("]");
|
|
@ -0,0 +1,9 @@
|
||||||
|
spring.cloud.config.name=resource
|
||||||
|
spring.cloud.config.discovery.service-id=config
|
||||||
|
spring.cloud.config.discovery.enabled=true
|
||||||
|
spring.cloud.config.username=configUser
|
||||||
|
spring.cloud.config.password=configPassword
|
||||||
|
|
||||||
|
eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka
|
||||||
|
|
||||||
|
server.port=8084
|
|
@ -0,0 +1,174 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.preemptive;
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.response.Response;
|
||||||
|
|
||||||
|
import org.baeldung.persistence.model.Book;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = { SpringCloudRestClientApplication.class }, webEnvironment = WebEnvironment.DEFINED_PORT)
|
||||||
|
public class RestApiLiveTest {
|
||||||
|
|
||||||
|
private static final String API_URI = "http://localhost:8084/books";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
RestAssured.authentication = preemptive().basic("user", "userPass");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetAllBooks_thenOK() {
|
||||||
|
final Response response = RestAssured.get(API_URI);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetCreatedBookById_thenOK() {
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
final String location = createBookAsUri(book);
|
||||||
|
|
||||||
|
final Response response = RestAssured.get(location);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertEquals(book.getTitle(), response.jsonPath()
|
||||||
|
.get("title"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetCreatedBookByName_thenOK() {
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
createBookAsUri(book);
|
||||||
|
|
||||||
|
final Response response = RestAssured.get(API_URI + "/search/findByTitle?title=" + book.getTitle());
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertTrue(response.jsonPath()
|
||||||
|
.getLong("page.totalElements") > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetNotExistBookById_thenNotFound() {
|
||||||
|
final Response response = RestAssured.get(API_URI + "/" + randomNumeric(4));
|
||||||
|
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetNotExistBookByName_thenNotFound() {
|
||||||
|
final Response response = RestAssured.get(API_URI + "/search/findByTitle?title=" + randomAlphabetic(20));
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertTrue(response.jsonPath()
|
||||||
|
.getLong("page.totalElements") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST
|
||||||
|
@Test
|
||||||
|
public void whenCreateNewBook_thenCreated() {
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(book)
|
||||||
|
.post(API_URI);
|
||||||
|
assertEquals(HttpStatus.CREATED.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateDuplicateBook_thenError() {
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
createBookAsUri(book);
|
||||||
|
|
||||||
|
// duplicate
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(book)
|
||||||
|
.post(API_URI);
|
||||||
|
assertEquals(HttpStatus.CONFLICT.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInvalidBook_thenError() {
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
book.setAuthor(null);
|
||||||
|
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(book)
|
||||||
|
.post(API_URI);
|
||||||
|
assertEquals(HttpStatus.CONFLICT.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUpdateCreatedBook_thenUpdated() {
|
||||||
|
// create
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
final String location = createBookAsUri(book);
|
||||||
|
|
||||||
|
// update
|
||||||
|
book.setAuthor("newAuthor");
|
||||||
|
Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(book)
|
||||||
|
.put(location);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
|
||||||
|
// check if changes saved
|
||||||
|
response = RestAssured.get(location);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertEquals("newAuthor", response.jsonPath()
|
||||||
|
.get("author"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeleteCreatedBook_thenOk() {
|
||||||
|
// create
|
||||||
|
final Book book = createRandomBook();
|
||||||
|
final String location = createBookAsUri(book);
|
||||||
|
|
||||||
|
// delete
|
||||||
|
Response response = RestAssured.delete(location);
|
||||||
|
assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatusCode());
|
||||||
|
|
||||||
|
// confirm it was deleted
|
||||||
|
response = RestAssured.get(location);
|
||||||
|
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeleteNotExistBook_thenError() {
|
||||||
|
final Response response = RestAssured.delete(API_URI + "/" + randomNumeric(4));
|
||||||
|
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================== Util
|
||||||
|
|
||||||
|
private Book createRandomBook() {
|
||||||
|
final Book book = new Book();
|
||||||
|
book.setTitle(randomAlphabetic(10));
|
||||||
|
book.setAuthor(randomAlphabetic(15));
|
||||||
|
return book;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createBookAsUri(Book book) {
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(book)
|
||||||
|
.post(API_URI);
|
||||||
|
return response.jsonPath()
|
||||||
|
.get("_links.self.href");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.response.Response;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = { SpringCloudRestClientApplication.class, SessionConfig.class }, webEnvironment = WebEnvironment.DEFINED_PORT)
|
||||||
|
public class SessionLiveTest {
|
||||||
|
|
||||||
|
private Jedis jedis;
|
||||||
|
private static final String API_URI = "http://localhost:8084/books";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
jedis = new Jedis("localhost", 6379);
|
||||||
|
jedis.flushAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenStart_thenNoSessionsExist() {
|
||||||
|
final Set<String> result = jedis.keys("*");
|
||||||
|
assertEquals(0, result.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUnauthorizeUser_whenAccessResources_then_unAuthorized() {
|
||||||
|
final Response response = RestAssured.get(API_URI);
|
||||||
|
assertEquals(HttpStatus.UNAUTHORIZED.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthorizedUser_whenDeleteSession_thenUnauthorized() {
|
||||||
|
// authorize User
|
||||||
|
Response response = RestAssured.given()
|
||||||
|
.auth()
|
||||||
|
.preemptive()
|
||||||
|
.basic("user", "userPass")
|
||||||
|
.get(API_URI);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
final String sessionCookie = response.getCookie("SESSION");
|
||||||
|
|
||||||
|
// check redis
|
||||||
|
final Set<String> redisResult = jedis.keys("*");
|
||||||
|
assertTrue(redisResult.size() > 0);
|
||||||
|
|
||||||
|
// login with cookie
|
||||||
|
response = RestAssured.given()
|
||||||
|
.cookie("SESSION", sessionCookie)
|
||||||
|
.get(API_URI);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
|
||||||
|
// empty redis
|
||||||
|
jedis.flushAll();
|
||||||
|
|
||||||
|
// login with cookie again
|
||||||
|
response = RestAssured.given()
|
||||||
|
.cookie("SESSION", sessionCookie)
|
||||||
|
.get(API_URI);
|
||||||
|
assertEquals(HttpStatus.UNAUTHORIZED.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#### cloud
|
||||||
|
spring.application.name=spring-cloud-eureka-client
|
||||||
|
server.port=8084
|
||||||
|
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka}
|
||||||
|
eureka.instance.preferIpAddress=true
|
||||||
|
|
||||||
|
#### persistence
|
||||||
|
spring.datasource.driver-class-name=org.h2.Driver
|
||||||
|
spring.datasource.url=jdbc:h2:mem:cloud_rest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=
|
||||||
|
|
||||||
|
#### security
|
||||||
|
security.basic.enabled=true
|
||||||
|
security.basic.path=/**
|
||||||
|
security.user.name=user
|
||||||
|
security.user.password=userPass
|
||||||
|
security.user.role=USER
|
||||||
|
security.sessions=always
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.baeldung</groupId>
|
||||||
|
<artifactId>spring-cloud-rest-client-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-cloud-rest-client-2</name>
|
||||||
|
<description>Client Service for book reviews</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.4.3.RELEASE</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<rest-assured.version>3.0.1</rest-assured.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>Camden.SR4</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||||
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
|
@EnableRedisHttpSession
|
||||||
|
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableEurekaClient
|
||||||
|
public class SpringCloudRestClientApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringCloudRestClientApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.baeldung.persistence.dao;
|
||||||
|
|
||||||
|
import org.baeldung.persistence.model.BookReview;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
||||||
|
|
||||||
|
@RepositoryRestResource(collectionResourceRel = "reviews", path = "reviews")
|
||||||
|
public interface BookReviewRepository extends CrudRepository<BookReview, Long> {
|
||||||
|
Page<BookReview> findByBookId(@Param("bookId") long bookId, Pageable pageable);
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package org.baeldung.persistence.model;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class BookReview {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
private int rating;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Long bookId;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
public BookReview() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BookReview(String content, int rating, long bookId) {
|
||||||
|
super();
|
||||||
|
this.content = content;
|
||||||
|
this.rating = rating;
|
||||||
|
this.bookId = bookId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRating() {
|
||||||
|
return rating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRating(int rating) {
|
||||||
|
this.rating = rating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getBookId() {
|
||||||
|
return bookId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBookId(Long bookId) {
|
||||||
|
this.bookId = bookId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = (prime * result) + (int) (bookId ^ (bookId >>> 32));
|
||||||
|
result = (prime * result) + ((content == null) ? 0 : content.hashCode());
|
||||||
|
result = (prime * result) + (int) (id ^ (id >>> 32));
|
||||||
|
result = (prime * result) + rating;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final BookReview other = (BookReview) obj;
|
||||||
|
if (bookId != other.bookId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (content == null) {
|
||||||
|
if (other.content != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!content.equals(other.content)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (id != other.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (rating != other.rating) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("BookReview [id=")
|
||||||
|
.append(id)
|
||||||
|
.append(", content=")
|
||||||
|
.append(content)
|
||||||
|
.append(", rating=")
|
||||||
|
.append(rating)
|
||||||
|
.append(", bookId=")
|
||||||
|
.append(bookId)
|
||||||
|
.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
spring.cloud.config.name=resource
|
||||||
|
spring.cloud.config.discovery.service-id=config
|
||||||
|
spring.cloud.config.discovery.enabled=true
|
||||||
|
spring.cloud.config.username=configUser
|
||||||
|
spring.cloud.config.password=configPassword
|
||||||
|
|
||||||
|
eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka
|
||||||
|
|
||||||
|
server.port=8085
|
|
@ -0,0 +1,162 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.preemptive;
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.response.Response;
|
||||||
|
|
||||||
|
import org.baeldung.persistence.model.BookReview;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = { SpringCloudRestClientApplication.class }, webEnvironment = WebEnvironment.DEFINED_PORT)
|
||||||
|
public class RestApiLiveTest {
|
||||||
|
|
||||||
|
private static final String API_URI = "http://localhost:8085/reviews";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
RestAssured.authentication = preemptive().basic("user", "userPass");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetAllReviews_thenOK() {
|
||||||
|
final Response response = RestAssured.get(API_URI);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetCreatedReviewById_thenOK() {
|
||||||
|
final BookReview review = createRandomReview();
|
||||||
|
final String location = createReviewAsUri(review);
|
||||||
|
|
||||||
|
final Response response = RestAssured.get(location);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertEquals(review.getContent(), response.jsonPath()
|
||||||
|
.get("content"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetCreatedReviewByName_thenOK() {
|
||||||
|
final BookReview review = createRandomReview();
|
||||||
|
createReviewAsUri(review);
|
||||||
|
|
||||||
|
final Response response = RestAssured.get(API_URI + "/search/findByBookId?bookId=" + review.getBookId());
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertTrue(response.jsonPath()
|
||||||
|
.getLong("page.totalElements") > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetNotExistReviewById_thenNotFound() {
|
||||||
|
final Response response = RestAssured.get(API_URI + "/" + randomNumeric(4));
|
||||||
|
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetNotExistReviewByName_thenNotFound() {
|
||||||
|
final Response response = RestAssured.get(API_URI + "/search/findByBookId?bookId=" + randomNumeric(4));
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertTrue(response.jsonPath()
|
||||||
|
.getLong("page.totalElements") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST
|
||||||
|
@Test
|
||||||
|
public void whenCreateNewReview_thenCreated() {
|
||||||
|
final BookReview review = createRandomReview();
|
||||||
|
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(review)
|
||||||
|
.post(API_URI);
|
||||||
|
assertEquals(HttpStatus.CREATED.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInvalidReview_thenError() {
|
||||||
|
final BookReview review = createRandomReview();
|
||||||
|
review.setBookId(null);
|
||||||
|
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(review)
|
||||||
|
.post(API_URI);
|
||||||
|
assertEquals(HttpStatus.CONFLICT.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUpdateCreatedReview_thenUpdated() {
|
||||||
|
// create
|
||||||
|
final BookReview review = createRandomReview();
|
||||||
|
final String location = createReviewAsUri(review);
|
||||||
|
|
||||||
|
// update
|
||||||
|
review.setRating(4);
|
||||||
|
Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(review)
|
||||||
|
.put(location);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
|
||||||
|
// check if changes saved
|
||||||
|
response = RestAssured.get(location);
|
||||||
|
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
|
||||||
|
assertEquals(4, response.jsonPath()
|
||||||
|
.getInt("rating"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeleteCreatedReview_thenOk() {
|
||||||
|
// create
|
||||||
|
final BookReview review = createRandomReview();
|
||||||
|
final String location = createReviewAsUri(review);
|
||||||
|
|
||||||
|
// delete
|
||||||
|
Response response = RestAssured.delete(location);
|
||||||
|
assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatusCode());
|
||||||
|
|
||||||
|
// confirm it was deleted
|
||||||
|
response = RestAssured.get(location);
|
||||||
|
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeleteNotExistReview_thenError() {
|
||||||
|
final Response response = RestAssured.delete(API_URI + "/" + randomNumeric(4));
|
||||||
|
assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================== Util
|
||||||
|
|
||||||
|
private BookReview createRandomReview() {
|
||||||
|
final BookReview review = new BookReview();
|
||||||
|
review.setContent(randomAlphabetic(10));
|
||||||
|
review.setRating(3);
|
||||||
|
review.setBookId(1L);
|
||||||
|
return review;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createReviewAsUri(BookReview review) {
|
||||||
|
final Response response = RestAssured.given()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
.body(review)
|
||||||
|
.post(API_URI);
|
||||||
|
return response.jsonPath()
|
||||||
|
.get("_links.self.href");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class SpringCloudRestClientApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#### cloud
|
||||||
|
spring.application.name=spring-cloud-eureka-client
|
||||||
|
server.port=8085
|
||||||
|
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka}
|
||||||
|
eureka.instance.preferIpAddress=true
|
||||||
|
|
||||||
|
#### persistence
|
||||||
|
spring.datasource.driver-class-name=org.h2.Driver
|
||||||
|
spring.datasource.url=jdbc:h2:mem:cloud_rest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=
|
||||||
|
|
||||||
|
#### security
|
||||||
|
security.basic.enabled=true
|
||||||
|
security.basic.path=/**
|
||||||
|
security.user.name=user
|
||||||
|
security.user.password=userPass
|
||||||
|
security.user.role=USER
|
||||||
|
security.sessions=always
|
|
@ -1,10 +0,0 @@
|
||||||
package org.baeldung.persistence.dao;
|
|
||||||
|
|
||||||
import org.baeldung.persistence.model.Book;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
|
||||||
|
|
||||||
@RepositoryRestResource(collectionResourceRel = "books", path = "books")
|
|
||||||
public interface BookRepository extends JpaRepository<Book, Long> {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
spring.application.name=spring-cloud-eureka-client
|
|
||||||
server.port=0
|
|
||||||
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8761/eureka}
|
|
||||||
eureka.instance.preferIpAddress=true
|
|
||||||
|
|
||||||
spring.datasource.driver-class-name=org.h2.Driver
|
|
||||||
spring.datasource.url=jdbc:h2:mem:cloud_rest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
|
||||||
spring.datasource.username=sa
|
|
||||||
spring.datasource.password=
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
nbproject/private/
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
|
@ -4,46 +4,39 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>org.baeldung</groupId>
|
<groupId>org.baeldung</groupId>
|
||||||
<artifactId>spring-cloud-rest-client</artifactId>
|
<artifactId>spring-cloud-rest-config</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>spring-cloud-rest</name>
|
<name>spring-cloud-rest-config</name>
|
||||||
<description>Demo project for Spring Boot</description>
|
<description>Spring Cloud REST configuration server</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.4.3.RELEASE</version>
|
<version>1.4.3.RELEASE</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<spring-cloud.version>Camden.SR4</spring-cloud.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-config-server</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-eureka</artifactId>
|
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-rest</artifactId>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -58,7 +51,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
<version>Camden.SR4</version>
|
<version>${spring-cloud.version}</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -71,6 +64,16 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.config.server.EnableConfigServer;
|
||||||
|
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableConfigServer
|
||||||
|
@EnableEurekaClient
|
||||||
|
public class SpringCloudRestConfigApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringCloudRestConfigApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
server.port=8081
|
||||||
|
spring.application.name=config
|
||||||
|
|
||||||
|
spring.cloud.config.server.git.uri=${HOME}/application-config
|
||||||
|
|
||||||
|
eureka.client.region = default
|
||||||
|
eureka.client.registryFetchIntervalSeconds = 5
|
||||||
|
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka}
|
||||||
|
|
||||||
|
security.user.name=configUser
|
||||||
|
security.user.password=configPassword
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class SpringCloudRestConfigApplicationTests {
|
||||||
|
@Test
|
||||||
|
public void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
|
|
|
@ -26,10 +26,26 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-config</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-eureka-server</artifactId>
|
<artifactId>spring-cloud-starter-eureka-server</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -56,6 +72,16 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||||
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
|
||||||
|
@EnableRedisHttpSession
|
||||||
|
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
server.port=8761
|
|
||||||
eureka.client.registerWithEureka=false
|
|
||||||
eureka.client.fetchRegistry=false
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
spring.cloud.config.name=spring-cloud-rest-server
|
||||||
|
spring.cloud.config.uri=http://localhost:8081
|
||||||
|
spring.cloud.config.username=configUser
|
||||||
|
spring.cloud.config.password=configPassword
|
|
@ -41,7 +41,11 @@
|
||||||
<version>${hibernate-validator.version}</version>
|
<version>${hibernate-validator.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-fileupload</groupId>
|
||||||
|
<artifactId>commons-fileupload</artifactId>
|
||||||
|
<version>${fileupload.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<profiles>
|
<profiles>
|
||||||
<!-- Local -->
|
<!-- Local -->
|
||||||
|
@ -93,6 +97,7 @@
|
||||||
<maven-compiler-plugin.source>1.8</maven-compiler-plugin.source>
|
<maven-compiler-plugin.source>1.8</maven-compiler-plugin.source>
|
||||||
<hibernate-validator.version>5.3.3.Final</hibernate-validator.version>
|
<hibernate-validator.version>5.3.3.Final</hibernate-validator.version>
|
||||||
<deploy-path>enter-location-of-server</deploy-path>
|
<deploy-path>enter-location-of-server</deploy-path>
|
||||||
|
<fileupload.version>1.3.2</fileupload.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.baeldung.springmvcforms.configuration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.multipart.MultipartResolver;
|
||||||
|
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
||||||
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
@ -26,4 +28,10 @@ class ApplicationConfiguration extends WebMvcConfigurerAdapter {
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MultipartResolver multipartResolver() {
|
||||||
|
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
|
||||||
|
multipartResolver.setMaxUploadSize(5242880);
|
||||||
|
return multipartResolver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.springmvcforms.controller;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class FileUploadController implements HandlerExceptionResolver {
|
||||||
|
|
||||||
|
@RequestMapping(value = "/uploadFile", method = RequestMethod.GET)
|
||||||
|
public String getImageView() {
|
||||||
|
return "file";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
|
||||||
|
public ModelAndView uploadFile(MultipartFile file) throws IOException{
|
||||||
|
ModelAndView modelAndView = new ModelAndView("file");
|
||||||
|
|
||||||
|
InputStream in = file.getInputStream();
|
||||||
|
File currDir = new File(".");
|
||||||
|
String path = currDir.getAbsolutePath();
|
||||||
|
FileOutputStream f = new FileOutputStream(path.substring(0, path.length()-1)+ file.getOriginalFilename());
|
||||||
|
int ch = 0;
|
||||||
|
while ((ch = in.read()) != -1) {
|
||||||
|
f.write(ch);
|
||||||
|
}
|
||||||
|
f.flush();
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
modelAndView.getModel().put("message", "File uploaded successfully!");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exc) {
|
||||||
|
ModelAndView modelAndView = new ModelAndView("file");
|
||||||
|
if (exc instanceof MaxUploadSizeExceededException) {
|
||||||
|
modelAndView.getModel().put("message", "File size exceeds limit!");
|
||||||
|
}
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.springmvcforms.interceptor;
|
||||||
|
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
public class FileUploadExceptionAdvice {
|
||||||
|
|
||||||
|
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||||
|
public ModelAndView handleMaxSizeException(MaxUploadSizeExceededException exc, HttpServletRequest request, HttpServletResponse response){
|
||||||
|
ModelAndView modelAndView = new ModelAndView("file");
|
||||||
|
modelAndView.getModel().put("message", "File too large!");
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||||
|
pageEncoding="ISO-8859-1"%>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Upload file</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<c:url value="/uploadFile" var="uploadFileUrl" />
|
||||||
|
<form method="post" enctype="multipart/form-data" action="${uploadFileUrl}">
|
||||||
|
<input type="file" name="file"/>
|
||||||
|
<input type="submit" value="Upload file"/>
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
${message }
|
||||||
|
<br /> <br />
|
||||||
|
<form method="GET" action="${uploadFileUrl}" >
|
||||||
|
<input type="submit" value="Reset" />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -14,3 +14,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
- [Returning Image/Media Data with Spring MVC](http://www.baeldung.com/spring-mvc-image-media-data)
|
- [Returning Image/Media Data with Spring MVC](http://www.baeldung.com/spring-mvc-image-media-data)
|
||||||
- [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind)
|
- [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind)
|
||||||
- [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp)
|
- [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp)
|
||||||
|
- [Exploring SpringMVC’s Form Tag Library](http://www.baeldung.com/spring-mvc-form-tags)
|
||||||
|
|
|
@ -39,6 +39,17 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
## Spring Remoting Tutorials Project
|
||||||
|
|
||||||
|
### Relevant Articles
|
||||||
|
- [Intro to Spring Remoting with HTTP Invokers](http://www.baeldung.com/spring-remoting-http-invoker)
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
This Maven project contains the Java source code for various modules used in the Spring Remoting series of articles.
|
||||||
|
|
||||||
|
### Building the Project
|
||||||
|
You can build the project using Maven inside your IDE or from the command line:
|
||||||
|
```
|
||||||
|
mvn clean install
|
||||||
|
```
|
|
@ -3,65 +3,24 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.4.3.RELEASE</version>
|
||||||
|
</parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>spring-remoting</artifactId>
|
<artifactId>spring-remoting</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<description>Parent for all projects related to Spring Remoting.</description>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
<java.version>1.8</java.version>
|
||||||
<maven-war-plugin.version>3.0.0</maven-war-plugin.version>
|
|
||||||
|
|
||||||
<servlet.version>3.1.0</servlet.version>
|
|
||||||
<logback.version>1.1.8</logback.version>
|
|
||||||
<spring.version>4.3.5.RELEASE</spring.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- spring -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-core</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-context</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-web</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-webmvc</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- logback -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-core</artifactId>
|
|
||||||
<version>${logback.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<version>${logback.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- servlet -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<version>${servlet.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- companion modules -->
|
<!-- companion modules -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
@ -73,35 +32,6 @@
|
||||||
|
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>${maven-compiler-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<debug>true</debug>
|
|
||||||
<optimize>true</optimize>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<showDeprecation>true</showDeprecation>
|
|
||||||
<showWarnings>true</showWarnings>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<!-- This special setup for maven-war-plugin is needed to use Servlet 3 annotation based configuration, where a WEB-INF/web.xml is not strictl needed. -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
<configuration>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>remoting-http</module>
|
<module>remoting-http</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.baeldung.api;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class Address implements Serializable{
|
|
||||||
|
|
||||||
private String address;
|
|
||||||
private String countryCode;
|
|
||||||
|
|
||||||
public Address(String address, String countryCode) {
|
|
||||||
this.address = address;
|
|
||||||
this.countryCode = countryCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCountryCode() {
|
|
||||||
return countryCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String toString() {
|
|
||||||
return address + " (" + countryCode + ")";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +1,17 @@
|
||||||
package com.baeldung.api;
|
package com.baeldung.api;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
public class Booking implements Serializable {
|
public class Booking implements Serializable {
|
||||||
|
|
||||||
private int costInCent;
|
|
||||||
private int etaInSeconds;
|
|
||||||
private String bookingCode;
|
private String bookingCode;
|
||||||
private LocalDateTime pickUptime;
|
|
||||||
private Address pickUpAddress;
|
|
||||||
private Address dropOffAddress;
|
|
||||||
|
|
||||||
public Booking(Address pickUpAddress, LocalDateTime pickUptime, Address dropOffAddress, int costInCent, int etaInSeconds, String bookingCode) {
|
|
||||||
this.costInCent = costInCent;
|
|
||||||
this.etaInSeconds = etaInSeconds;
|
|
||||||
this.bookingCode = bookingCode;
|
|
||||||
this.pickUptime = pickUptime;
|
|
||||||
this.pickUpAddress = pickUpAddress;
|
|
||||||
this.dropOffAddress = dropOffAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCostInCent() {
|
|
||||||
return costInCent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEtaInSeconds() {
|
|
||||||
return etaInSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBookingCode() {
|
|
||||||
return bookingCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getPickUptime() {
|
|
||||||
return pickUptime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Address getDropOffAddress() {
|
|
||||||
return dropOffAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String toString() {
|
@Override public String toString() {
|
||||||
return String.format("Booking: pick up @ %tr in %s, drop down in %s after %d minutes, %.2f $.", pickUptime, pickUpAddress, dropOffAddress, etaInSeconds / 60, costInCent / 100.0);
|
return format("Ride confirmed: code '%s'.", bookingCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public Booking(String bookingCode) {
|
||||||
System.out.println(new Booking(new Address("a", "b"),
|
this.bookingCode = bookingCode;
|
||||||
LocalDateTime.now(), new Address("c", "d"), 123_00, 600, "abc"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package com.baeldung.api;
|
package com.baeldung.api;
|
||||||
|
|
||||||
public interface CabBookingService {
|
public interface CabBookingService {
|
||||||
Booking bookPickUp(Address pickUpLocation, Address dropOffLocation, int pax) throws BookingException;
|
Booking bookRide(String pickUpLocation) throws BookingException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,22 +9,22 @@
|
||||||
<artifactId>spring-remoting-http</artifactId>
|
<artifactId>spring-remoting-http</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>spring-remoting-http-client</artifactId>
|
<artifactId>spring-remoting-http-client</artifactId>
|
||||||
<description>Shows how to invoke a remote service using Spring Remoting.</description>
|
<description>Shows how to invoke a remote service using Spring Remoting HTTP.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- spring -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- companion modules -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>api</artifactId>
|
<artifactId>api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,21 +0,0 @@
|
||||||
package com.baeldug.client;
|
|
||||||
|
|
||||||
import com.baeldung.api.*;
|
|
||||||
|
|
||||||
public class CabBookingClient {
|
|
||||||
|
|
||||||
private CabBookingService cabService;
|
|
||||||
|
|
||||||
public CabBookingClient(CabBookingService cabService) {
|
|
||||||
this.cabService = cabService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() throws BookingException {
|
|
||||||
|
|
||||||
Address pickUp = new Address("13 Seagate Blvd, Key Largo, FL 33037", "US");
|
|
||||||
Address dropDown = new Address("91831 Overseas Hwy, Tavernier, FL 33070", "US");
|
|
||||||
System.out.println( cabService.bookPickUp(pickUp, dropDown, 3) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldug.client;
|
||||||
|
|
||||||
|
import com.baeldung.api.BookingException;
|
||||||
|
import com.baeldung.api.CabBookingService;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
|
||||||
|
|
||||||
|
import static java.lang.System.out;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class Client {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HttpInvokerProxyFactoryBean invoker() {
|
||||||
|
HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
|
||||||
|
invoker.setServiceUrl("http://localhost:8080/booking");
|
||||||
|
invoker.setServiceInterface(CabBookingService.class);
|
||||||
|
return invoker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws BookingException {
|
||||||
|
CabBookingService service = SpringApplication.run(Client.class, args).getBean(CabBookingService.class);
|
||||||
|
out.println(service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
package com.baeldug.client;
|
|
||||||
|
|
||||||
import com.baeldung.api.CabBookingService;
|
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class Main {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HttpInvokerProxyFactoryBean invoker() {
|
|
||||||
HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
|
|
||||||
invoker.setServiceUrl("http://localhost:9090/spring-remoting-http-server/booking");
|
|
||||||
invoker.setServiceInterface(CabBookingService.class);
|
|
||||||
return invoker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public CabBookingClient client(CabBookingService service){
|
|
||||||
return new CabBookingClient(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
AnnotationConfigApplicationContext rootContext =
|
|
||||||
new AnnotationConfigApplicationContext();
|
|
||||||
rootContext.scan(Main.class.getPackage().getName());
|
|
||||||
rootContext.refresh();
|
|
||||||
CabBookingClient bean = rootContext.getBean(CabBookingClient.class);
|
|
||||||
bean.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue