diff --git a/spring-boot/src/main/java/com/baeldung/intro/App.java b/spring-boot/src/main/java/com/baeldung/intro/App.java
new file mode 100644
index 0000000000..30e1c2b5ba
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/intro/App.java
@@ -0,0 +1,13 @@
+package com.baeldung.intro;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App
+{
+ public static void main( String[] args )
+ {
+ SpringApplication.run(App.class, args);
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java b/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java
new file mode 100644
index 0000000000..9109b0a292
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java
@@ -0,0 +1,18 @@
+package com.baeldung.intro.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HomeController {
+
+ @RequestMapping("/")
+ public String root(){
+ return "Index Page";
+ }
+
+ @RequestMapping("/local")
+ public String local(){
+ return "/local";
+ }
+}
diff --git a/spring-boot/src/main/resources/public/error/404.html b/spring-boot/src/main/resources/public/error/404.html
new file mode 100644
index 0000000000..02d6092bee
--- /dev/null
+++ b/spring-boot/src/main/resources/public/error/404.html
@@ -0,0 +1,8 @@
+
+
+ RESOURCE NOT FOUND
+
+
+ 404 RESOURCE NOT FOUND
+
+
\ No newline at end of file
diff --git a/spring-boot/src/test/java/com/baeldung/intro/AppTest.java b/spring-boot/src/test/java/com/baeldung/intro/AppTest.java
new file mode 100644
index 0000000000..749fe68838
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/intro/AppTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.intro;
+
+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.status;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+public class AppTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void getIndex() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Index Page")));
+ }
+
+ @Test
+ public void getLocal() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("/local")));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-rest/pom.xml b/spring-cloud/spring-cloud-rest/pom.xml
index fef6d93cfc..3424d988a9 100644
--- a/spring-cloud/spring-cloud-rest/pom.xml
+++ b/spring-cloud/spring-cloud-rest/pom.xml
@@ -8,7 +8,8 @@
1.0.0-SNAPSHOT
spring-cloud-rest-server
- spring-cloud-rest-client
+ spring-cloud-rest-client-1
+ spring-cloud-rest-client-2
pom
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/pom.xml
similarity index 98%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/pom.xml
index 21c19be834..f50ae7e8f2 100644
--- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/pom.xml
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/pom.xml
@@ -4,7 +4,7 @@
4.0.0
org.baeldung
- spring-cloud-rest-client
+ spring-cloud-rest-client-1
0.0.1-SNAPSHOT
jar
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/SessionConfig.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/SessionConfig.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/SessionConfig.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/SessionConfig.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/SpringCloudRestClientApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/SpringCloudRestClientApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/SpringCloudRestClientApplication.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/SpringCloudRestClientApplication.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/dao/BookRepository.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/persistence/dao/BookRepository.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/dao/BookRepository.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/persistence/dao/BookRepository.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/model/Book.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/persistence/model/Book.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/java/org/baeldung/persistence/model/Book.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/java/org/baeldung/persistence/model/Book.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/application.properties
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/main/resources/application.properties
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/application.properties
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/RestApiLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/java/org/baeldung/RestApiLiveTest.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/RestApiLiveTest.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/java/org/baeldung/RestApiLiveTest.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/SessionLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/java/org/baeldung/SessionLiveTest.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/SessionLiveTest.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/java/org/baeldung/SessionLiveTest.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/resources/application.properties
similarity index 100%
rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-client/src/test/resources/application.properties
rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/test/resources/application.properties
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/pom.xml
new file mode 100644
index 0000000000..359045829b
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/pom.xml
@@ -0,0 +1,107 @@
+
+
+ 4.0.0
+
+ org.baeldung
+ spring-cloud-rest-client-2
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-cloud-rest
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.3.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 3.0.1
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-eureka
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-rest
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.session
+ spring-session
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.rest-assured
+ rest-assured
+ ${rest-assured.version}
+
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ Camden.SR4
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/*IntegrationTest.java
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/SessionConfig.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/SessionConfig.java
new file mode 100644
index 0000000000..bd1c0013ca
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/SessionConfig.java
@@ -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 {
+}
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/SpringCloudRestClientApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/SpringCloudRestClientApplication.java
new file mode 100644
index 0000000000..a13aaa54bc
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/SpringCloudRestClientApplication.java
@@ -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);
+ }
+}
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/persistence/dao/BookReviewRepository.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/persistence/dao/BookReviewRepository.java
new file mode 100644
index 0000000000..2107786d62
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/persistence/dao/BookReviewRepository.java
@@ -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 {
+ Page findByBookId(@Param("bookId") long bookId, Pageable pageable);
+}
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/persistence/model/BookReview.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/persistence/model/BookReview.java
new file mode 100644
index 0000000000..5341df7cb6
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/java/org/baeldung/persistence/model/BookReview.java
@@ -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();
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties
new file mode 100644
index 0000000000..65fcb7b71e
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties
@@ -0,0 +1,19 @@
+#### cloud
+spring.application.name=spring-cloud-eureka-client
+server.port=0
+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
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java
new file mode 100644
index 0000000000..022648ffa1
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java
@@ -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:8084/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");
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java
new file mode 100644
index 0000000000..c16adfbb34
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/SpringCloudRestClientApplicationTests.java
@@ -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() {
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties
new file mode 100644
index 0000000000..ece9ca1d94
--- /dev/null
+++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties
@@ -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
\ No newline at end of file
diff --git a/spring-remoting/pom.xml b/spring-remoting/pom.xml
index 2e3b7e76f8..a43dd52a3e 100644
--- a/spring-remoting/pom.xml
+++ b/spring-remoting/pom.xml
@@ -3,65 +3,24 @@
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">
4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.3.RELEASE
+
com.baeldung
spring-remoting
1.0-SNAPSHOT
+ Parent for all projects related to Spring Remoting.
pom
- 3.6.0
- 3.0.0
-
- 3.1.0
- 1.1.8
- 4.3.5.RELEASE
+ 1.8
-
-
- org.springframework
- spring-core
- ${spring.version}
-
-
- org.springframework
- spring-context
- ${spring.version}
-
-
- org.springframework
- spring-web
- ${spring.version}
-
-
- org.springframework
- spring-webmvc
- ${spring.version}
-
-
-
-
- ch.qos.logback
- logback-core
- ${logback.version}
-
-
- ch.qos.logback
- logback-classic
- ${logback.version}
-
-
-
-
- javax.servlet
- javax.servlet-api
- ${servlet.version}
- provided
-
-
${project.groupId}
@@ -73,35 +32,6 @@
-
-
-
-
-
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- true
- true
-
- 1.8
- UTF-8
- true
- true
-
-
-
-
- maven-war-plugin
- 3.0.0
-
- false
-
-
-
-
-
-
remoting-http
diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java
deleted file mode 100644
index f2382fabd9..0000000000
--- a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java
+++ /dev/null
@@ -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 + ")";
- }
-}
diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java
index 7bec4e162d..5d2d3683a1 100644
--- a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java
+++ b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java
@@ -1,52 +1,17 @@
package com.baeldung.api;
import java.io.Serializable;
-import java.time.LocalDateTime;
+
+import static java.lang.String.format;
public class Booking implements Serializable {
-
- private int costInCent;
- private int etaInSeconds;
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() {
- 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 {
- System.out.println(new Booking(new Address("a", "b"),
- LocalDateTime.now(), new Address("c", "d"), 123_00, 600, "abc"));
+ public Booking(String bookingCode) {
+ this.bookingCode = bookingCode;
}
}
diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java
index 25b27264e8..b554415e07 100644
--- a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java
+++ b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java
@@ -1,5 +1,5 @@
package com.baeldung.api;
public interface CabBookingService {
- Booking bookPickUp(Address pickUpLocation, Address dropOffLocation, int pax) throws BookingException;
+ Booking bookRide(String pickUpLocation) throws BookingException;
}
diff --git a/spring-remoting/remoting-http/client/pom.xml b/spring-remoting/remoting-http/client/pom.xml
index 77891c106a..94a536fc18 100644
--- a/spring-remoting/remoting-http/client/pom.xml
+++ b/spring-remoting/remoting-http/client/pom.xml
@@ -9,22 +9,22 @@
spring-remoting-http
1.0-SNAPSHOT
-
spring-remoting-http-client
- Shows how to invoke a remote service using Spring Remoting.
-
+ Shows how to invoke a remote service using Spring Remoting HTTP.
-
- org.springframework
- spring-web
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
-
-
${project.groupId}
api
-
\ No newline at end of file
diff --git a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java
deleted file mode 100644
index 9669970403..0000000000
--- a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java
+++ /dev/null
@@ -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) );
-
- }
-
-}
diff --git a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Client.java b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Client.java
new file mode 100644
index 0000000000..90f6736a43
--- /dev/null
+++ b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Client.java
@@ -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"));
+ }
+
+}
diff --git a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java
deleted file mode 100644
index a5e3ccd912..0000000000
--- a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java
+++ /dev/null
@@ -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();
- }
-
-}
diff --git a/spring-remoting/remoting-http/pom.xml b/spring-remoting/remoting-http/pom.xml
index 0d08779bd7..117d4ec295 100644
--- a/spring-remoting/remoting-http/pom.xml
+++ b/spring-remoting/remoting-http/pom.xml
@@ -9,9 +9,8 @@
1.0-SNAPSHOT
spring-remoting-http
- Parent for all modules related to HTTP Spring Remoting
+ Parent for all modules related to HTTP Spring Remoting.
pom
-
server
client
diff --git a/spring-remoting/remoting-http/server/pom.xml b/spring-remoting/remoting-http/server/pom.xml
index 32a99716a5..517f4451f7 100644
--- a/spring-remoting/remoting-http/server/pom.xml
+++ b/spring-remoting/remoting-http/server/pom.xml
@@ -8,58 +8,16 @@
spring-remoting-http
1.0-SNAPSHOT
- war
-
spring-remoting-http-server
- Shows how to expose a service using Spring Remoting
-
-
- 2.2
-
-
+ Shows how to expose a service using Spring Remoting HTTP.
-
-
-
-
- org.springframework
- spring-webmvc
+ org.springframework.boot
+ spring-boot-starter-web
-
-
-
- javax.servlet
- javax.servlet-api
-
-
-
${project.groupId}
api
-
-
-
-
-
- maven-compiler-plugin
-
-
-
- maven-war-plugin
-
-
-
- org.apache.tomcat.maven
- tomcat7-maven-plugin
- ${tomcat7-maven-plugin.version}
-
- 9090
-
-
-
-
-
\ No newline at end of file
diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java
deleted file mode 100644
index 146d2ecadb..0000000000
--- a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.baeldung.server;
-
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class CabBookingConfig {
-
-
-
-}
diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java
deleted file mode 100644
index 53b3fd5faf..0000000000
--- a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.baeldung.server;
-
-import org.springframework.web.WebApplicationInitializer;
-import org.springframework.web.context.ContextLoaderListener;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-import org.springframework.web.servlet.DispatcherServlet;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletRegistration;
-
-public class CabBookingInitializer implements WebApplicationInitializer {
-
- @Override
- public void onStartup(ServletContext container) {
- AnnotationConfigWebApplicationContext rootContext =
- new AnnotationConfigWebApplicationContext();
- rootContext.register(CabBookingConfig.class);
-
- // Manage the lifecycle of the root application context
- container.addListener(new ContextLoaderListener(rootContext));
-
- // Create the dispatcher servlet's Spring application context
- AnnotationConfigWebApplicationContext dispatcherContext =
- new AnnotationConfigWebApplicationContext();
- dispatcherContext.register(DispatcherConfig.class);
-
- // Register and map the dispatcher servlet
- ServletRegistration.Dynamic dispatcher =
- container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
- dispatcher.setLoadOnStartup(1);
- dispatcher.addMapping("/*");
- }
-
-}
diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java
index 8f3c099fe0..55ec9c5733 100644
--- a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java
+++ b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java
@@ -1,27 +1,16 @@
package com.baeldung.server;
-import com.baeldung.api.Address;
import com.baeldung.api.Booking;
import com.baeldung.api.BookingException;
import com.baeldung.api.CabBookingService;
-import java.time.LocalDateTime;
-
import static java.lang.Math.random;
-import static java.time.LocalDateTime.now;
-import static java.time.temporal.ChronoUnit.MINUTES;
import static java.util.UUID.randomUUID;
public class CabBookingServiceImpl implements CabBookingService {
- @Override public Booking bookPickUp(Address pickUpLocation, Address dropOffLocation, int pax) throws BookingException {
- if (random() < 0.3) {
- throw new BookingException("Cab unavailable");
- }
- int tripTimeInMinutes = (int) (5 + random() * 15);
- int costInCent = 15_00 + tripTimeInMinutes * 5 * pax;
- LocalDateTime pickUpDate = now().plus(15L * (long) (random() * 10), MINUTES);
-
- return new Booking(pickUpLocation, pickUpDate, dropOffLocation, costInCent, tripTimeInMinutes * 60, randomUUID().toString());
+ @Override public Booking bookRide(String pickUpLocation) throws BookingException {
+ if (random() < 0.3) throw new BookingException("Cab unavailable");
+ return new Booking(randomUUID().toString());
}
}
diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/Server.java
similarity index 62%
rename from spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java
rename to spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/Server.java
index 8f9391f8ac..c6b198507f 100644
--- a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java
+++ b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/Server.java
@@ -1,12 +1,17 @@
package com.baeldung.server;
import com.baeldung.api.CabBookingService;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
@Configuration
-public class DispatcherConfig {
+@ComponentScan
+@EnableAutoConfiguration
+public class Server {
@Bean(name = "/booking") HttpInvokerServiceExporter accountService() {
HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
@@ -15,4 +20,8 @@ public class DispatcherConfig {
return exporter;
}
-}
+ public static void main(String[] args) {
+ SpringApplication.run(Server.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-remoting/remoting-http/server/src/main/resources/logback.xml b/spring-remoting/remoting-http/server/src/main/resources/logback.xml
deleted file mode 100644
index 566c44b448..0000000000
--- a/spring-remoting/remoting-http/server/src/main/resources/logback.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
- ${logPattern}
-
-
-
-
-
-
-
\ No newline at end of file