You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2018/09/07 14:25:03 UTC
[incubator-servicecomb-saga] 01/02: SCB-820 Updated the inventory
example
This is an automated email from the ASF dual-hosted git repository.
ningjiang pushed a commit to branch SCB-820
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git
commit a7f7ad719de67cb3864d8cdb9dfec4b06c77d6a3
Author: Willem Jiang <ji...@huawei.com>
AuthorDate: Fri Sep 7 20:29:02 2018 +0800
SCB-820 Updated the inventory example
---
saga-demo/tcc-spring-demo/inventory/pom.xml | 13 ++-
.../saga/demo/pack/inventory/InventoryService.java | 73 ++++++++-----
.../saga/demo/pack/inventory/Product.java | 5 +
.../demo/pack/inventory/ProductController.java | 89 ++++++---------
.../saga/demo/pack/inventory/ProductDao.java | 5 +
.../saga/demo/pack/inventory/ProductOrder.java | 82 ++++++++++++++
.../pack/inventory/TccInventoryApplication.java | 7 +-
.../inventory/src/main/resources/application.yaml | 17 ++-
.../demo/pack/inventory/InventoryServiceTest.java | 119 +++++++++++++++++++++
.../demo/pack/inventory/ProductControllerTest.java | 77 +++++++++++++
.../saga/demo/pack/inventory/TestApplication.java} | 8 +-
.../saga/demo/pack/ordering/OrderService.java | 4 +
.../saga/demo/pack/payment/Payment.java | 4 +
13 files changed, 399 insertions(+), 104 deletions(-)
diff --git a/saga-demo/tcc-spring-demo/inventory/pom.xml b/saga-demo/tcc-spring-demo/inventory/pom.xml
index 25f90d6..6c2a218 100644
--- a/saga-demo/tcc-spring-demo/inventory/pom.xml
+++ b/saga-demo/tcc-spring-demo/inventory/pom.xml
@@ -43,10 +43,6 @@
<artifactId>omega-spring-starter</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.servicecomb.saga</groupId>
- <artifactId>omega-transport-resttemplate</artifactId>
- </dependency>
- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
@@ -58,6 +54,15 @@
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>javax.persistence-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java
index f5c36d7..37e97c8 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java
@@ -16,7 +16,13 @@
*/
package org.apache.servicecomb.saga.demo.pack.inventory;
+import java.util.Collection;
+import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.transaction.Transactional;
+
import org.apache.servicecomb.saga.omega.transaction.annotations.Participate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -24,45 +30,54 @@ import org.springframework.stereotype.Service;
@Service
public class InventoryService {
+ private Map<Integer, ProductOrder> orders = new ConcurrentHashMap<>();
+ @Autowired
private ProductDao productDao;
- /**
- * Find the product with specific product Id.
- *
- * @param productId Product ID
- * @param requiredCount Required product count
- * @return return the reserved count, 0 if nothing is available. returns negative value if
- * insufficient.
- */
@Participate(confirmMethod = "confirm", cancelMethod = "cancel")
- public Integer reserve(Long productId, int requiredCount) {
- Product product = productDao.findOne(productId);
- if (Objects.isNull(product)) {
- throw new IllegalArgumentException("Product not exists at all");
- }
-
- // if it is sufficient
- if (product.getInStock() > requiredCount) {
- product.setInStock(product.getInStock() - requiredCount);
- productDao.save(product);
- return requiredCount;
+ @Transactional
+ public void reserve(ProductOrder order) {
+ Product product = getProduct(order.getProductName());
+ if (product.getInStock() > order.getAmount()) {
+ product.setInStock(product.getInStock() - order.getAmount());
+ productDao.saveAndFlush(product);
+ orders.put(order.getId(), order);
} else {
- return product.getInStock() - requiredCount;
+ throw new IllegalArgumentException("The Product is out of stock!");
}
}
- public void confirm(Long productId, int requiredCount) {
- // empty body
+ public void confirm(ProductOrder order) {
+ order.setConfirmed(true);
}
- public void cancel(Long productId, int requiredCount) {
- Product product = productDao.findOne(productId);
- product.setInStock(product.getInStock() + requiredCount);
- productDao.save(product);
+ @Transactional
+ public void cancel(ProductOrder order) {
+ Product product = productDao.findProduceByName(order.getProductName());
+ product.setInStock(product.getInStock() + order.getAmount());
+ productDao.saveAndFlush(product);
+ order.setCancelled(true);
}
- @Autowired
- public void setProductDao(ProductDao productDao) {
- this.productDao = productDao;
+ @Transactional
+ private Product getProduct(String productName) {
+ Product product = productDao.findProduceByName(productName);
+ if (Objects.isNull(product)) {
+ throw new IllegalArgumentException("Product not exists at all!");
+ }
+ return product;
+ }
+
+ Integer getInventory(String productName) {
+ Product product = getProduct(productName);
+ return product.getInStock();
+ }
+
+ Collection<ProductOrder> getAllOrders() {
+ return orders.values();
+ }
+
+ void clearAllOrders() {
+ orders.clear();
}
}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java
index 9ddc7e4..d8804f5 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java
@@ -22,6 +22,8 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
+import javax.persistence.Version;
+
@Entity
@Table(name = "t_product")
@@ -38,6 +40,9 @@ public class Product implements Serializable {
*/
private Integer inStock;
+ @Version
+ private Integer version;
+
Product() {
}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java
index dbf187a..076721f 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java
@@ -16,76 +16,53 @@
*/
package org.apache.servicecomb.saga.demo.pack.inventory;
-import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+@RequestMapping("/products")
@Controller
-@RequestMapping("/product")
public class ProductController {
-
- private InventoryService inventoryService;
-
- @PostMapping("/product")
- public Response updateInventory(@RequestParam("productId") Long productId,
- @RequestParam("requiredCount") Integer requiredCount) {
- return new Response(0, "OK",
- ImmutableList.of(inventoryService.reserve(productId, requiredCount)));
- }
-
- @ExceptionHandler
- public Response exceptionHandler(Exception e) {
- return new Response(-1, e.getMessage(),
- ImmutableList.of(e.getStackTrace()));
- }
-
@Autowired
- public void setInventoryService(
- InventoryService inventoryService) {
- this.inventoryService = inventoryService;
- }
-}
-
-class Response {
-
- private int code;
-
- private String message;
-
- private List<Object> objects;
-
- Response(int code, String message, List<Object> objects) {
- this.code = code;
- this.message = message;
- this.objects = objects;
- }
-
- public int getCode() {
- return code;
- }
-
- public void setCode(int code) {
- this.code = code;
- }
+ private InventoryService inventoryService;
- public String getMessage() {
- return message;
+ private final AtomicInteger id = new AtomicInteger(0);
+
+ @PostMapping("/order/{userName}/{productName}/{amount}")
+ @ResponseBody
+ public ProductOrder updateInventory(@PathVariable String userName,
+ @PathVariable String productName, @PathVariable Integer amount) {
+ ProductOrder order = new ProductOrder();
+ order.setId(id.incrementAndGet());
+ order.setUserName(userName);
+ order.setProductName(productName);
+ order.setAmount(amount);
+ inventoryService.reserve(order);
+ return order;
}
- public void setMessage(String message) {
- this.message = message;
+ @CrossOrigin
+ @GetMapping("/orders")
+ @ResponseBody
+ List<ProductOrder> getAll() {
+ return new ArrayList<>(inventoryService.getAllOrders());
}
- public List<Object> getObjects() {
- return objects;
+ @DeleteMapping("/orders")
+ void clear() {
+ inventoryService.clearAllOrders();
+ id.set(0);
}
- public void setObjects(List<Object> objects) {
- this.objects = objects;
- }
}
+
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java
index 42bcd4b..7a93664 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java
@@ -16,8 +16,13 @@
*/
package org.apache.servicecomb.saga.demo.pack.inventory;
+
import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
public interface ProductDao extends JpaRepository<Product, Long> {
+ @Query("select p from Product p where p.name =?1 ")
+ Product findProduceByName(String ProductName);
+
}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductOrder.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductOrder.java
new file mode 100644
index 0000000..ebb074e
--- /dev/null
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductOrder.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.saga.demo.pack.inventory;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+@JsonAutoDetect(fieldVisibility = Visibility.ANY)
+public class ProductOrder {
+ @JsonIgnore
+ private Integer id;
+ private String userName;
+ private String productName;
+ private Integer amount;
+ private boolean confirmed;
+ private boolean cancelled;
+
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Integer getAmount() {
+ return amount;
+ }
+
+ public void setAmount(Integer amount) {
+ this.amount = amount;
+ }
+
+ public boolean isConfirmed() {
+ return confirmed;
+ }
+
+ public void setConfirmed(boolean confirmed) {
+ this.confirmed = confirmed;
+ }
+
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java
index 92c415c..878c156 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java
@@ -22,8 +22,10 @@ import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Profile;
@SpringBootApplication
+@Profile("prd")
@EnableOmega
public class TccInventoryApplication {
@@ -34,7 +36,10 @@ public class TccInventoryApplication {
@Bean
CommandLineRunner kickOff(ProductDao productDao) {
return args -> {
- productDao.save(new Product("Bottled water", 100));
+ // Set up the inventory
+ productDao.save(new Product("ProductA", 100));
+ productDao.save(new Product("ProductB", 10));
+ productDao.save(new Product("ProductC", 1));
};
}
}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml b/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml
index 98b79a6..fd05d0b 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml
+++ b/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml
@@ -18,20 +18,15 @@ spring:
application:
name: inventory
datasource:
- url: jdbc:h2:mem:inventory-test
+ url: jdbc:h2:mem:inventory
h2:
console:
enabled: true
jpa:
- show-sql: true
- generate-ddl: true
- hibernate:
- ddl-auto: create-drop
- naming:
- physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
- implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ properties:
+ eclipselink:
+ ddl-generation: none
+
alpha:
cluster:
- address: ${alpha-server.servicecomb.io:localhost}:8080
-server:
- port: 10020
\ No newline at end of file
+ address: alpha-server.servicecomb.io:8080
diff --git a/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryServiceTest.java b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryServiceTest.java
new file mode 100644
index 0000000..0842f2c
--- /dev/null
+++ b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryServiceTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.saga.demo.pack.inventory;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.fail;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+// Using test profile to avoid the Omega connection
+@ActiveProfiles("test")
+@SpringBootTest(classes = {TestApplication.class})
+public class InventoryServiceTest {
+ @Autowired
+ private InventoryService inventoryService;
+
+ @Autowired
+ private ProductDao productDao;
+
+ private ProductOrder order = new ProductOrder();
+
+ @Before
+ public void setup() {
+ productDao.save(new Product("ProductA", 100));
+ productDao.save(new Product("ProductB", 10));
+ productDao.save(new Product("ProductC", 1));
+
+ }
+
+ @After
+ public void cleanUp() {
+ productDao.deleteAll();
+ inventoryService.clearAllOrders();
+ }
+
+ @Test
+ public void testInventoryServiceWithConfirmation() {
+ order.setId(1);
+ order.setUserName("user1");
+ order.setAmount(10);
+ order.setProductName("ProductA");
+ inventoryService.reserve(order);
+ assertThat(inventoryService.getInventory("ProductA"), is(90));
+ assertThat(inventoryService.getAllOrders().size(), is(1));
+
+ inventoryService.confirm(order);
+ assertThat(order.isCancelled(), is(false));
+ assertThat(order.isConfirmed(), is(true));
+ assertThat(inventoryService.getInventory("ProductA"), is(90));
+ }
+
+ @Test
+ public void getNoExitProductFromInventoryService() {
+ order.setId(1);
+ order.setAmount(10);
+ order.setProductName("Product");
+ try {
+ inventoryService.reserve(order);
+ fail("Expect exception here");
+ } catch (Exception ex) {
+ assertThat(ex.getMessage(), is("Product not exists at all!"));
+ }
+ assertThat(inventoryService.getAllOrders().size(), is(0));
+ }
+
+ @Test
+ public void getProductOutOfStockFromInventoryService() {
+ order.setAmount(10);
+ order.setProductName("ProductC");
+ try {
+ inventoryService.reserve(order);
+ fail("Expect exception here");
+ } catch (Exception ex) {
+ assertThat(ex.getMessage(), is("The Product is out of stock!"));
+ }
+ assertThat(inventoryService.getAllOrders().size(), is(0));
+ }
+
+ @Test
+ public void testInventoryServiceWithCancel() {order.setUserName("user1");
+ order.setId(1);
+ order.setAmount(10);
+ order.setProductName("ProductA");
+ inventoryService.reserve(order);
+ assertThat(inventoryService.getInventory("ProductA"), is(90));
+ assertThat(inventoryService.getAllOrders().size(), is(1));
+
+ inventoryService.cancel(order);
+ assertThat(order.isCancelled(), is(true));
+ assertThat(order.isConfirmed(), is(false));
+ assertThat(inventoryService.getAllOrders().size(), is(1));
+ assertThat(inventoryService.getInventory("ProductA"), is(100));
+ }
+
+}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductControllerTest.java b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductControllerTest.java
new file mode 100644
index 0000000..8dcc7dd
--- /dev/null
+++ b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductControllerTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.saga.demo.pack.inventory;
+
+import static java.util.Collections.singletonList;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(ProductController.class)
+public class ProductControllerTest {
+ private final ProductOrder someOrder = someOrder();
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @MockBean
+ private InventoryService inventoryService;
+
+ @Before
+ public void setUp() {
+ when(inventoryService.getAllOrders()).thenReturn(singletonList(someOrder));
+ }
+
+ @Test
+ public void retrievesOrdersFromRepo() throws Exception {
+ mockMvc.perform(get("/products/orders"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$", hasSize(1)))
+ .andExpect(jsonPath("$.[0].userName", is(someOrder.getUserName())))
+ .andExpect(jsonPath("$.[0].productName", is(someOrder.getProductName())))
+ .andExpect(jsonPath("$.[0].confirmed", is(someOrder.isConfirmed())))
+ .andExpect(jsonPath("$.[0].cancelled", is(someOrder.isCancelled())))
+ .andExpect(jsonPath("$.[0].amount", is(someOrder.getAmount())));
+ }
+
+ private ProductOrder someOrder() {
+ ProductOrder order = new ProductOrder();
+ order.setId(1);
+ order.setProductName("ProductName1");
+ order.setUserName("UserName");
+ order.setAmount(100);
+ order.setCancelled(false);
+ order.setConfirmed(true);
+ return order;
+ }
+
+}
diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/TestApplication.java
similarity index 85%
copy from saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java
copy to saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/TestApplication.java
index 42bcd4b..7a28136 100644
--- a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java
+++ b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/TestApplication.java
@@ -14,10 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.servicecomb.saga.demo.pack.inventory;
-import org.springframework.data.jpa.repository.JpaRepository;
+package org.apache.servicecomb.saga.demo.pack.inventory;
-public interface ProductDao extends JpaRepository<Product, Long> {
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+@SpringBootApplication
+public class TestApplication {
+ // Just for testing
}
diff --git a/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/OrderService.java b/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/OrderService.java
new file mode 100644
index 0000000..99564aa
--- /dev/null
+++ b/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/OrderService.java
@@ -0,0 +1,4 @@
+package org.apache.servicecomb.saga.demo.pack.ordering;
+
+public class OrderService {
+}
diff --git a/saga-demo/tcc-spring-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/pack/payment/Payment.java b/saga-demo/tcc-spring-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/pack/payment/Payment.java
new file mode 100644
index 0000000..1349787
--- /dev/null
+++ b/saga-demo/tcc-spring-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/pack/payment/Payment.java
@@ -0,0 +1,4 @@
+package org.apache.servicecomb.saga.demo.pack.payment;
+
+public class Payment {
+}