├── order ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── distribute │ │ │ │ └── order │ │ │ │ ├── dao │ │ │ │ ├── UserDao.java │ │ │ │ └── OrderDao.java │ │ │ │ ├── OrderApplication.java │ │ │ │ ├── exception │ │ │ │ └── GlobalException.java │ │ │ │ ├── service │ │ │ │ └── impl │ │ │ │ │ ├── UserServiceImpl.java │ │ │ │ │ └── OrderServiceImpl.java │ │ │ │ └── controller │ │ │ │ └── OrderController.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── distribute │ │ └── order │ │ └── OrderApplicationTests.java ├── .gitignore ├── pom.xml ├── mvnw.cmd └── mvnw ├── message ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── .gitignore ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── distribute │ │ │ │ └── message │ │ │ │ ├── dao │ │ │ │ ├── DbLogDao.java │ │ │ │ └── TransactionMessageDao.java │ │ │ │ ├── MessageApplication.java │ │ │ │ ├── service │ │ │ │ ├── activemq │ │ │ │ │ └── ActiveMqQueueServiceImpl.java │ │ │ │ └── impl │ │ │ │ │ ├── DbLogServiceImpl.java │ │ │ │ │ └── TransactionMessageServiceImpl.java │ │ │ │ └── task │ │ │ │ └── Task.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── distribute │ │ └── message │ │ └── MessageApplicationTests.java ├── pom.xml ├── mvnw.cmd └── mvnw ├── product ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── .gitignore ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── distribute │ │ │ │ └── product │ │ │ │ ├── ProductApplication.java │ │ │ │ ├── dao │ │ │ │ └── ProductDao.java │ │ │ │ └── service │ │ │ │ └── impl │ │ │ │ ├── ProductServiceImpl.java │ │ │ │ └── ProductConsumerListener.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── distribute │ │ └── product │ │ └── ProductApplicationTests.java ├── pom.xml ├── mvnw.cmd └── mvnw ├── api-service ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── distribute │ │ │ ├── common │ │ │ ├── enums │ │ │ │ ├── IsDelete.java │ │ │ │ ├── MessageStatus.java │ │ │ │ ├── PayType.java │ │ │ │ └── ErrorCode.java │ │ │ └── utils │ │ │ │ └── Constant.java │ │ │ ├── service │ │ │ ├── MessageQueueService.java │ │ │ ├── OrderService.java │ │ │ ├── ProductService.java │ │ │ ├── UserService.java │ │ │ ├── DbLogService.java │ │ │ └── TransactionMessageService.java │ │ │ ├── OrderDetail.java │ │ │ ├── message │ │ │ └── domain │ │ │ │ ├── DbLog.java │ │ │ │ └── TransactionMessage.java │ │ │ ├── order │ │ │ └── domain │ │ │ │ ├── User.java │ │ │ │ ├── OrderDetails.java │ │ │ │ └── Orders.java │ │ │ └── product │ │ │ └── domain │ │ │ └── Product.java │ └── test │ │ └── java │ │ └── PostTest.java ├── pom.xml └── api-service.iml ├── .gitignore ├── pom.xml ├── consis.iml ├── README.md └── LICENSE /order/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanglinyong/consis/HEAD/order/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /message/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanglinyong/consis/HEAD/message/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /product/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanglinyong/consis/HEAD/product/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /order/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /message/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /product/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/common/enums/IsDelete.java: -------------------------------------------------------------------------------- 1 | package com.distribute.common.enums; 2 | 3 | /** 4 | * Created by wly on 2018/8/22. 5 | */ 6 | public enum IsDelete { 7 | YES,NO 8 | } 9 | -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.dao; 2 | 3 | import com.distribute.order.domain.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by Administrator on 2018/8/23. 8 | */ 9 | public interface UserDao extends JpaRepository { 10 | User findById(long id); 11 | } 12 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/common/utils/Constant.java: -------------------------------------------------------------------------------- 1 | package com.distribute.common.utils; 2 | 3 | /** 4 | * Created by wly on 2018/8/23. 5 | */ 6 | public class Constant { 7 | public static final String ORDER_QUEUE_NAME = "ORDER_QUEUE"; 8 | 9 | public static final String MESSAGE_UNDEAD = "0"; 10 | 11 | public static final String MESSAGE_SENDING = "1"; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/dao/OrderDao.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.dao; 2 | 3 | 4 | import com.distribute.order.domain.Orders; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * Created by Administrator on 2018/8/23. 9 | */ 10 | public interface OrderDao extends JpaRepository { 11 | Orders findById(long id); 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /message/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /order/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /product/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/service/MessageQueueService.java: -------------------------------------------------------------------------------- 1 | package com.distribute.service; 2 | 3 | /** 4 | * 消息队列接口 5 | * Created by Administrator on 2018/8/22. 6 | */ 7 | public interface MessageQueueService { 8 | /** 9 | * 发送消息到消息队列 10 | * 11 | * @param queueName 队列名称 12 | * @param messageBody 消息内容 13 | */ 14 | void sendMessageToMessageQueue(String queueName, String messageBody); 15 | } 16 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/dao/DbLogDao.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.dao; 2 | 3 | import com.distribute.message.domain.DbLog; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by Administrator on 2018/8/23. 8 | */ 9 | public interface DbLogDao extends JpaRepository { 10 | DbLog findById(long id); 11 | 12 | DbLog findByMessageId(String messageId); 13 | 14 | void deleteByMessageId(String messageId); 15 | } 16 | -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/OrderApplication.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | @EntityScan("com.distribute.order.domain") 7 | @SpringBootApplication 8 | public class OrderApplication { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(OrderApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /product/src/main/java/com/distribute/product/ProductApplication.java: -------------------------------------------------------------------------------- 1 | package com.distribute.product; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | 7 | @EntityScan("com.distribute.product.domain") 8 | @SpringBootApplication 9 | public class ProductApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ProductApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/common/enums/MessageStatus.java: -------------------------------------------------------------------------------- 1 | package com.distribute.common.enums; 2 | 3 | /** 4 | * Created by Administrator on 2018/8/22. 5 | */ 6 | public enum MessageStatus { 7 | WAITING_CONFIRM("0", "待确认"), 8 | 9 | SENDING("1", "发送中"); 10 | 11 | private String key; 12 | 13 | private String value; 14 | 15 | MessageStatus(String key ,String value){ 16 | this.key = key; 17 | this.value = value; 18 | } 19 | 20 | public String getKey() { 21 | return key; 22 | } 23 | 24 | public String getValue() { 25 | return value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.distribute.service; 2 | 3 | 4 | import com.distribute.order.domain.Orders; 5 | 6 | /** 7 | * Created by Administrator on 2018/8/22. 8 | */ 9 | public interface OrderService { 10 | /** 11 | * 添加订单 12 | * @param order 13 | */ 14 | void add(Orders order); 15 | 16 | /** 17 | * 删除订单 18 | * @param id 19 | */ 20 | void delete(long id); 21 | 22 | /** 23 | * 更新订单 24 | * @param order 25 | */ 26 | void update(Orders order); 27 | 28 | /** 29 | * 根据id查询订单 30 | * @param id 31 | * @return 32 | */ 33 | Orders findById(long id); 34 | } 35 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/MessageApplication.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | 8 | @EnableScheduling 9 | @EntityScan("com.distribute.message.domain") 10 | @SpringBootApplication 11 | public class MessageApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(MessageApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.distribute.consis 8 | consis 9 | 1.0-SNAPSHOT 10 | 11 | api-service 12 | order 13 | product 14 | message 15 | 16 | pom 17 | 18 | 19 | -------------------------------------------------------------------------------- /product/src/main/java/com/distribute/product/dao/ProductDao.java: -------------------------------------------------------------------------------- 1 | package com.distribute.product.dao; 2 | 3 | import com.distribute.product.domain.Product; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by Administrator on 2018/8/23. 12 | */ 13 | public interface ProductDao extends JpaRepository { 14 | Product findById(long id); 15 | 16 | @Query(value = "select * from product where id in (:ids)",nativeQuery = true) 17 | List findByIds(@Param( value = "ids") Long[] ids); 18 | } 19 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/OrderDetail.java: -------------------------------------------------------------------------------- 1 | package com.distribute; 2 | 3 | import com.distribute.product.domain.Product; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Created by wly on 2018/8/24. 9 | */ 10 | public class OrderDetail implements Serializable{ 11 | private Long id; 12 | private Integer num; 13 | private Product product; 14 | 15 | public Product getProduct() { 16 | return product; 17 | } 18 | 19 | public void setProduct(Product product) { 20 | this.product = product; 21 | } 22 | 23 | public Long getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Long id) { 28 | this.id = id; 29 | } 30 | 31 | public Integer getNum() { 32 | return num; 33 | } 34 | 35 | public void setNum(Integer num) { 36 | this.num = num; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/exception/GlobalException.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.exception; 2 | 3 | import com.distribute.common.enums.ErrorCode; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * Created by wly on 2018/8/26. 13 | */ 14 | @ControllerAdvice 15 | public class GlobalException { 16 | @ExceptionHandler(RuntimeException.class) 17 | @ResponseBody 18 | public Map exceptionHandler(){ 19 | Map map = new HashMap( ); 20 | map.put( "result", ErrorCode.SYS_EXCEPTION.getCode() ); 21 | return map; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /order/src/test/java/com/distribute/order/OrderApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order; 2 | 3 | import com.distribute.OrderDetail; 4 | import com.distribute.order.domain.Orders; 5 | import com.distribute.service.OrderService; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import java.util.List; 13 | 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | public class OrderApplicationTests { 17 | @Autowired 18 | private OrderService orderService; 19 | @Test 20 | public void contextLoads() { 21 | Orders order = orderService.findById( 16l ); 22 | System.out.println(order.getList()+"============"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /order/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #配置数据源 2 | spring.datasource.url = jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8 3 | spring.datasource.username = root 4 | spring.datasource.password = root 5 | spring.datasource.driverClassName = com.mysql.jdbc.Driver 6 | 7 | #自动生成表 8 | spring.jpa.properties.hibernate.hbm2ddl.auto=update 9 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 10 | spring.jpa.show-sql= true 11 | spring.datasource.hikari.connectionInitSql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; 12 | 13 | server.port=8082 14 | spring.dubbo.application.name=order-consumer 15 | spring.dubbo.registry.address=zookeeper://localhost:2181 16 | spring.dubbo.protocol.name=dubbo 17 | spring.dubbo.protocol.port=20882 18 | spring.dubbo.scan=com.distribute.order.controller,com.distribute.order.service 19 | 20 | 21 | -------------------------------------------------------------------------------- /consis.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/common/enums/PayType.java: -------------------------------------------------------------------------------- 1 | package com.distribute.common.enums; 2 | 3 | public enum PayType { 4 | WXPAY("1", "微信公众号支付"), ALIPAY("2", "支付宝支付"), WXAPPPAY("3", "微信app支付"); 5 | 6 | private String payKey; 7 | private String payName; 8 | 9 | PayType(String payKey, String payName) { 10 | this.payKey = payKey; 11 | this.payName = payName; 12 | } 13 | 14 | public String getPayKey() { 15 | return payKey; 16 | } 17 | 18 | public String getPayName() { 19 | return payName; 20 | } 21 | 22 | public static PayType getPayType(String payKey) { 23 | PayType type = null; 24 | for (PayType payType : PayType.values()) { 25 | if (payType.getPayKey().equals(payKey)) { 26 | type = payType; 27 | } 28 | } 29 | return type; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/service/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.distribute.service; 2 | 3 | 4 | import com.distribute.product.domain.Product; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Administrator on 2018/8/22. 10 | */ 11 | public interface ProductService { 12 | /** 13 | * 根据id查询商品 14 | * @param id 15 | * @return 16 | */ 17 | Product findById(long id); 18 | 19 | /** 20 | * 添加商品 21 | * @param product 22 | */ 23 | void add(Product product); 24 | 25 | /** 26 | * 根据id删除商品 27 | * @param id 28 | */ 29 | void delete(long id); 30 | 31 | /** 32 | * 更新商品 33 | * @param product 34 | */ 35 | void update(Product product); 36 | 37 | /** 38 | * 根据ids查询商品集合 39 | * @param ids 40 | * @return 41 | */ 42 | List findByIds(Long[] ids); 43 | 44 | /** 45 | * 查询所有商品 46 | * @return 47 | */ 48 | List findAll(); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /message/src/test/java/com/distribute/message/MessageApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message; 2 | 3 | import com.distribute.message.domain.TransactionMessage; 4 | import com.distribute.service.TransactionMessageService; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.util.List; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class MessageApplicationTests { 16 | @Autowired 17 | private TransactionMessageService transactionMessageService; 18 | @Test 19 | public void contextLoads() { 20 | List list = transactionMessageService.queryRetryList(); 21 | System.out.println(list.size()+"==========================="); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.distribute.service; 2 | 3 | 4 | import com.distribute.order.domain.User; 5 | 6 | /** 7 | * Created by Administrator on 2018/8/23. 8 | */ 9 | public interface UserService { 10 | /** 11 | * 添加用户 12 | * @param user 13 | */ 14 | void add(User user); 15 | 16 | /** 17 | * 根据id删除用户 18 | * @param id 19 | */ 20 | void deleteById(long id); 21 | 22 | /** 23 | * 更新用户 24 | * @param user 25 | */ 26 | void update(User user); 27 | 28 | /** 29 | * 根据id查询用户 30 | * @param id 31 | * @return 32 | */ 33 | User findById(long id); 34 | 35 | /** 36 | * 根据用户名密码查询用户 37 | * @param username 38 | * @param password 39 | * @return 40 | */ 41 | User findUsernameAndPassword(String username,String password); 42 | 43 | /** 44 | * 根据用户名查询用户 45 | * @param username 46 | * @return 47 | */ 48 | User findByUsername(String username); 49 | } 50 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/service/activemq/ActiveMqQueueServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.service.activemq; 2 | 3 | import com.alibaba.dubbo.config.annotation.Service; 4 | import com.distribute.service.MessageQueueService; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.jms.core.JmsMessagingTemplate; 9 | 10 | /** 11 | * Created by wly on 2018/8/24. 12 | */ 13 | @Service 14 | public class ActiveMqQueueServiceImpl implements MessageQueueService { 15 | private final Logger log = LoggerFactory.getLogger( this.getClass() ); 16 | @Autowired 17 | private JmsMessagingTemplate jmsTemplate; 18 | @Override 19 | public void sendMessageToMessageQueue(String queueName,final String messageBody) { 20 | 21 | jmsTemplate.convertAndSend( queueName,messageBody ); 22 | 23 | log.info(">>> 发送消息到mq 队列:{},消息内容:{}", queueName, messageBody); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/service/DbLogService.java: -------------------------------------------------------------------------------- 1 | package com.distribute.service; 2 | 3 | 4 | 5 | import com.distribute.message.domain.DbLog; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by Administrator on 2018/8/23. 11 | */ 12 | public interface DbLogService { 13 | /** 14 | * 添加日志 15 | * @param dbLog 16 | */ 17 | void add(DbLog dbLog); 18 | 19 | /** 20 | * 删除日志 21 | * @param dbLog 22 | */ 23 | void delete(DbLog dbLog); 24 | 25 | 26 | /** 27 | * 根据消息ID删除日志 28 | * @param messageId 29 | */ 30 | void deleteByMessageId(String messageId); 31 | 32 | /** 33 | * 更新日志 34 | * @param dbLog 35 | */ 36 | void update(DbLog dbLog); 37 | 38 | /** 39 | * 根据id查询日志 40 | * @param id 41 | * @return 42 | */ 43 | DbLog findById(long id); 44 | 45 | /** 46 | * 根据消息id查询日志 47 | * @param messageId 48 | * @return 49 | */ 50 | DbLog findByMesageId(String messageId); 51 | 52 | /** 53 | * 查询所有log日志 54 | * @return 55 | */ 56 | List findAll(); 57 | } 58 | -------------------------------------------------------------------------------- /api-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | consis 7 | com.distribute.consis 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | api-service 13 | jar 14 | 15 | 16 | javax.persistence 17 | persistence-api 18 | 1.0.2 19 | 20 | 21 | com.alibaba 22 | fastjson 23 | 1.2.46 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /product/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #配置数据源 2 | spring.datasource.url = jdbc:mysql://192.168.120.130:3306/demo?useUnicode=true&characterEncoding=utf8 3 | spring.datasource.username = root 4 | spring.datasource.password = root 5 | spring.datasource.driverClassName = com.mysql.jdbc.Driver 6 | 7 | #自动生成表 8 | spring.jpa.properties.hibernate.hbm2ddl.auto=update 9 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 10 | spring.jpa.show-sql= true 11 | spring.datasource.hikari.connectionInitSql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; 12 | 13 | #Activemq 14 | spring.activemq.broker-url=tcp://localhost:61616 15 | spring.activemq.in-memory=true 16 | #如果此处设置为true,需要加下activemq-pool依赖包,否则会自动配置失败,报JmsMessagingTemplate注入失败 17 | spring.activemq.pool.enabled=false 18 | 19 | ## Dubbo 服务提供者配置 20 | spring.dubbo.application.name=product-provider 21 | ## Dubbo 服务对象的注册中心zookeeper的地址和端口 22 | spring.dubbo.registry.address=zookeeper://localhost:2181 23 | ## 用Dubbo协议在20880端口暴露服务 24 | spring.dubbo.protocol.name=dubbo 25 | spring.dubbo.protocol.port=20881 26 | ## 包扫描范围 27 | spring.dubbo.scan=com.distribute.product.service.impl 28 | 29 | server.port=8083 -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.service.impl; 2 | 3 | import com.alibaba.dubbo.config.annotation.Service; 4 | import com.distribute.order.dao.UserDao; 5 | import com.distribute.order.domain.User; 6 | import com.distribute.service.UserService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | /** 10 | * Created by wly on 2018/8/23. 11 | */ 12 | @Service 13 | public class UserServiceImpl implements UserService { 14 | 15 | @Autowired 16 | private UserDao userDao; 17 | 18 | @Override 19 | public void add(User user) { 20 | userDao.save( user ); 21 | } 22 | 23 | @Override 24 | public void deleteById(long id) { 25 | userDao.deleteById( id ); 26 | } 27 | 28 | @Override 29 | public void update(User user) { 30 | userDao.save( user ); 31 | } 32 | 33 | @Override 34 | public User findById(long id) { 35 | return userDao.findById( id ); 36 | } 37 | 38 | @Override 39 | public User findUsernameAndPassword(String username, String password) { 40 | return null; 41 | } 42 | 43 | @Override 44 | public User findByUsername(String username) { 45 | return null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/dao/TransactionMessageDao.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.dao; 2 | 3 | import com.distribute.message.domain.TransactionMessage; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import javax.transaction.Transactional; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by Administrator on 2018/8/23. 13 | */ 14 | public interface TransactionMessageDao extends JpaRepository { 15 | TransactionMessage findByMessageId(String messageId); 16 | @Transactional 17 | void deleteByMessageId(String messageId); 18 | 19 | @Query(value = "select * from transaction_message where dead_message=:deadMessage and UNIX_TIMESTAMP(now())-UNIX_TIMESTAMP(modify_time)>:maxTimeOut and status=:status",nativeQuery = true) 20 | List queryRetryList(@Param( "deadMessage" ) String deadMessage,@Param( "maxTimeOut" )Long maxTimeOut,@Param( "status" )String status); 21 | 22 | @Query(value = "select id from transaction_message where dead_message= 1",nativeQuery = true) 23 | List queryDeadList(); 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 分布式事务--基于可靠消息的最终一致性解决方案demo 3 | 4 | ![Spring Boot 2.0](https://img.shields.io/badge/Spring%20Boot-2.0-brightgreen.svg) 5 | ![Mysql 5.6](https://img.shields.io/badge/Mysql-5.6-blue.svg) 6 | ![JDK 1.8](https://img.shields.io/badge/JDK-1.8-brightgreen.svg) 7 | ![Maven](https://img.shields.io/badge/Maven-3.3.9-yellowgreen.svg) 8 | 9 | 10 | ## 项目使用技术 11 | 12 | springboot、dubbo、zookeeper、定时任务 13 | 14 | ## 一、项目结构 15 | 16 | maven父子工程: 17 | 18 | 父工程:consis 19 | 20 | 子工程:api-service、order、product、message 21 | 22 | api-service:该项目主要是提供接口调用的,还包含实体类、枚举等一些通用内容 23 | 24 | order:该项目是专门处理订单相关操作的系统 25 | 26 | product:该项目是专门处理产品相关操作的系统 27 | 28 | message:该项目是提供消息服务的系统,好包括定时任务 29 | 30 | 31 | 它们的依赖关系如下图: 32 | 33 | ![enter image description here](https://images.gitbook.cn/a181d460-acf7-11e8-afe5-6ba901a27e1b) 34 | 35 | ## 二、启动项目 36 | 37 | 首先在不同的系统中建立自己对应的数据库,springdatajpa会自动帮你生成表 38 | 39 | 注意启动顺序,如下: 40 | 41 | * 启动zookeeper 42 | * 启动activemq 43 | * 启动tomcat,访问dubbo-admin管理控制台 44 | * 启动MessageApplication 45 | * 启动ProductApplication 46 | * 启动OrderApplication 47 | 48 | 启动成功后,就可以通过postman工具进行测试了 49 | 50 | 希望喜欢的朋友都能给个star支持一下!谢谢~ 51 | 52 | ![](https://raw.githubusercontent.com/wiki/wanglinyong/wanglinyong.github.io/ssm.png) -------------------------------------------------------------------------------- /api-service/api-service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/common/enums/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.distribute.common.enums; 2 | 3 | /** 4 | * Created by Administrator on 2018/8/24. 5 | */ 6 | public enum ErrorCode { 7 | 8 | SUCCESS("000000", "操作成功"), 9 | FAILED("999999","操作失败"), 10 | ParamError("000001", "参数错误!"), 11 | 12 | LOW_STOCKS("000010", "库存不足!"), 13 | 14 | SYS_EXCEPTION("000999","系统异常!"), 15 | 16 | LoginNameOrPassWordError("000100", "用户名或者密码错误!"), 17 | EmailUsed("000101","该邮箱已被注册"), 18 | UserNameUsed("000102","该登录名称已存在"), 19 | EmailNotRegister("000103","该邮箱地址未注册"), 20 | LinkOutdated("000104","该链接已过期,请重新请求"), 21 | PassWordError("000105","密码输入错误"), 22 | UserNameLengthLimit("000106","用户名长度超限"), 23 | LoginNameNotExists("000107","该用户未注册"), 24 | UserNameSame("000108","新用户名与原用户名一致"), 25 | 26 | FileEmpty("000400","上传文件为空"), 27 | LimitPictureSize("000401","图片大小必须小于2M"), 28 | LimitPictureType("000402","图片格式必须为'jpg'、'png'、'jpge'、'gif'、'bmp'"); 29 | 30 | 31 | 32 | private ErrorCode(String code, String msg) { 33 | this.code = code; 34 | this.msg = msg; 35 | } 36 | private String code; 37 | private String msg; 38 | 39 | public String getCode() { 40 | return code; 41 | } 42 | public String getMsg() { 43 | return msg; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /message/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #配置数据源 2 | spring.datasource.url = jdbc:mysql://192.168.120.130:3306/transaction?useUnicode=true&characterEncoding=utf8 3 | spring.datasource.username = root 4 | spring.datasource.password = root 5 | spring.datasource.driverClassName = com.mysql.jdbc.Driver 6 | 7 | #自动生成表 8 | spring.jpa.properties.hibernate.hbm2ddl.auto=update 9 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 10 | spring.jpa.show-sql= true 11 | spring.datasource.hikari.connectionInitSql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; 12 | 13 | #Activemq 14 | spring.activemq.broker-url=tcp://localhost:61616 15 | spring.activemq.in-memory=true 16 | #如果此处设置为true,需要加下activemq-pool依赖包,否则会自动配置失败,报JmsMessagingTemplate注入失败 17 | spring.activemq.pool.enabled=false 18 | 19 | 20 | ## Dubbo 服务提供者配置 21 | spring.dubbo.application.name=message-provider 22 | ## Dubbo 服务对象的注册中心zookeeper的地址和端口 23 | spring.dubbo.registry.address=zookeeper://localhost:2181 24 | ## 用Dubbo协议在20880端口暴露服务 25 | spring.dubbo.protocol.name=dubbo 26 | spring.dubbo.protocol.port=20880 27 | ## 包扫描范围 28 | spring.dubbo.scan=com.distribute.message.service 29 | 30 | server.port=8081 31 | 32 | #最大发送次数 33 | retry.maxsendtimes=5 34 | #最大过期时间60秒 35 | retry.maxTimeOut=60 -------------------------------------------------------------------------------- /product/src/main/java/com/distribute/product/service/impl/ProductServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.distribute.product.service.impl; 2 | 3 | import com.alibaba.dubbo.config.annotation.Service; 4 | import com.distribute.product.dao.ProductDao; 5 | import com.distribute.product.domain.Product; 6 | import com.distribute.service.ProductService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by wly on 2018/8/23. 13 | */ 14 | @Service 15 | public class ProductServiceImpl implements ProductService { 16 | @Autowired 17 | private ProductDao productDao; 18 | @Override 19 | public Product findById(long id) { 20 | return productDao.findById( id ); 21 | } 22 | 23 | @Override 24 | public void add(Product product) { 25 | productDao.save( product ); 26 | } 27 | 28 | @Override 29 | public void delete(long id) { 30 | productDao.deleteById( id ); 31 | } 32 | 33 | @Override 34 | public void update(Product product) { 35 | productDao.save( product ); 36 | } 37 | 38 | @Override 39 | public List findByIds(Long[] ids) { 40 | return productDao.findByIds( ids ); 41 | } 42 | 43 | @Override 44 | public List findAll() { 45 | return productDao.findAll(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/message/domain/DbLog.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.io.Serializable; 8 | import java.util.Date; 9 | 10 | /** 11 | * db日志 12 | * Created by wly on 2018/8/23. 13 | */ 14 | @Entity 15 | public class DbLog implements Serializable{ 16 | private static final long serialVersionUID = 1L; 17 | @Id 18 | @GeneratedValue(strategy= GenerationType.IDENTITY) 19 | private Long id; 20 | private String messageId; 21 | private Date createTime; 22 | private String state;//0:未处理 1:已处理 23 | 24 | public Long getId() { 25 | return id; 26 | } 27 | 28 | public void setId(Long id) { 29 | this.id = id; 30 | } 31 | 32 | public String getMessageId() { 33 | return messageId; 34 | } 35 | 36 | public void setMessageId(String messageId) { 37 | this.messageId = messageId; 38 | } 39 | 40 | public Date getCreateTime() { 41 | return createTime; 42 | } 43 | 44 | public void setCreateTime(Date createTime) { 45 | this.createTime = createTime; 46 | } 47 | 48 | public String getState() { 49 | return state; 50 | } 51 | 52 | public void setState(String state) { 53 | this.state = state; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/order/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | 10 | /** 11 | * 用户 12 | * Created by wly on 2018/8/23. 13 | */ 14 | @Entity 15 | public class User implements Serializable{ 16 | 17 | private static final long serialVersionUID = 1L; 18 | @Id 19 | @GeneratedValue(strategy= GenerationType.IDENTITY) 20 | private Long id; 21 | private String username; 22 | private String password; 23 | private BigDecimal balance;//余额 24 | 25 | public Long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(Long id) { 30 | this.id = id; 31 | } 32 | 33 | public String getUsername() { 34 | return username; 35 | } 36 | 37 | public void setUsername(String username) { 38 | this.username = username; 39 | } 40 | 41 | public String getPassword() { 42 | return password; 43 | } 44 | 45 | public void setPassword(String password) { 46 | this.password = password; 47 | } 48 | 49 | public BigDecimal getBalance() { 50 | return balance; 51 | } 52 | 53 | public void setBalance(BigDecimal balance) { 54 | this.balance = balance; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/order/domain/OrderDetails.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.domain; 2 | 3 | import com.distribute.product.domain.Product; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import java.io.Serializable; 10 | 11 | /** 12 | * 订单详情表 13 | * Created by wly on 2018/8/26. 14 | */ 15 | @Entity 16 | public class OrderDetails implements Serializable { 17 | private static final long serialVersionUID = 1L; 18 | 19 | @Id 20 | @GeneratedValue(strategy= GenerationType.IDENTITY) 21 | private Long id; 22 | 23 | private Long productId; 24 | 25 | private Integer num; 26 | 27 | private String orderCode; 28 | 29 | public Long getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Long id) { 34 | this.id = id; 35 | } 36 | 37 | public Long getProductId() { 38 | return productId; 39 | } 40 | 41 | public void setProductId(Long productId) { 42 | this.productId = productId; 43 | } 44 | 45 | public Integer getNum() { 46 | return num; 47 | } 48 | 49 | public void setNum(Integer num) { 50 | this.num = num; 51 | } 52 | 53 | public String getOrderCode() { 54 | return orderCode; 55 | } 56 | 57 | public void setOrderCode(String orderCode) { 58 | this.orderCode = orderCode; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/service/impl/DbLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.service.impl; 2 | 3 | import com.alibaba.dubbo.config.annotation.Service; 4 | import com.distribute.message.dao.DbLogDao; 5 | import com.distribute.message.domain.DbLog; 6 | import com.distribute.service.DbLogService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by wly on 2018/8/23. 13 | */ 14 | @Service 15 | public class DbLogServiceImpl implements DbLogService { 16 | @Autowired 17 | private DbLogDao dbLogDao; 18 | @Override 19 | public void add(DbLog dbLog) { 20 | dbLogDao.save( dbLog ); 21 | } 22 | 23 | @Override 24 | public void delete(DbLog dbLog) { 25 | dbLogDao.delete( dbLog ); 26 | } 27 | 28 | @Override 29 | public void deleteByMessageId(String messageId) { 30 | dbLogDao.deleteByMessageId(messageId); 31 | } 32 | 33 | @Override 34 | public void update(DbLog dbLog) { 35 | dbLogDao.save( dbLog ); 36 | } 37 | 38 | @Override 39 | public DbLog findById(long id) { 40 | return dbLogDao.findById( id ); 41 | } 42 | 43 | @Override 44 | public DbLog findByMesageId(String messageId) { 45 | return dbLogDao.findByMessageId( messageId ); 46 | } 47 | 48 | @Override 49 | public List findAll() { 50 | return dbLogDao.findAll(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /product/src/test/java/com/distribute/product/ProductApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.distribute.product; 2 | 3 | import com.distribute.product.domain.Product; 4 | import com.distribute.service.ProductService; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.math.BigDecimal; 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | @RunWith(SpringRunner.class) 16 | @SpringBootTest 17 | public class ProductApplicationTests { 18 | 19 | @Autowired 20 | private ProductService productService; 21 | 22 | @Test 23 | public void contextLoads() { 24 | Product product = new Product(); 25 | product.setCreateTime( new Date( ) ); 26 | product.setProductName( "锤子手机" ); 27 | product.setProductSku( 100l ); 28 | product.setProductPrice( new BigDecimal( 998.00 ) ); 29 | product.setProductSpec( "960X760" ); 30 | Product product2 = new Product(); 31 | product2.setCreateTime( new Date( ) ); 32 | product2.setProductName( "小米手机" ); 33 | product2.setProductSku( 100l ); 34 | product2.setProductPrice( new BigDecimal( 1666.99 ) ); 35 | product2.setProductSpec( "1024X760" ); 36 | productService.add( product ); 37 | productService.add( product2 ); 38 | Long[] arr = {1l,2l}; 39 | List list = productService.findByIds( arr ); 40 | System.out.println(list.get( 0 ).getProductName()+"=============="); 41 | /* 42 | List list = productService.findAll(); 43 | System.out.println(list.get( 0 ).getProductName()+"=============="); 44 | */ 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/service/TransactionMessageService.java: -------------------------------------------------------------------------------- 1 | package com.distribute.service; 2 | 3 | 4 | 5 | import com.distribute.message.domain.TransactionMessage; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by Administrator on 2018/8/22. 11 | */ 12 | public interface TransactionMessageService { 13 | /** 14 | * 预存储消息 15 | * @param messageId 消息编号 16 | * @param messageBody 消息内容 17 | * @param consumerQueue 队列名称 18 | * @return 消息编号 19 | */ 20 | String savePreparMessage(String messageId,String messageBody, String consumerQueue); 21 | 22 | /** 23 | * 确认并发送消息 24 | * 25 | * @param messageId 消息编号 26 | */ 27 | void confirmAndSend(String messageId) throws Exception; 28 | 29 | /** 30 | * 直接发送消息 31 | * 32 | * @param messageBody 消息内容 33 | * @param consumerQueue 队列名称 34 | */ 35 | void directSendMessage(String messageBody, String consumerQueue); 36 | 37 | /** 38 | * 根据messageId重发某条消息 39 | * 40 | * @param messageId 消息编号 41 | */ 42 | void retry(String messageId) throws Exception; 43 | 44 | /** 45 | * 根据消息ID删除消息 46 | * 47 | * @param messageId 消息编号 48 | */ 49 | void delete(String messageId); 50 | 51 | /** 52 | * 查询需要重试的消息列表 53 | * 54 | * @return 55 | */ 56 | List queryRetryList(); 57 | 58 | /** 59 | * 查询死亡消息(需人工处理的消息) 60 | * @return 61 | */ 62 | List queryDeadList(); 63 | 64 | /** 65 | * 根据消息编号查询消息 66 | * @param messageId 67 | * @return 68 | */ 69 | TransactionMessage findByMessageId(String messageId); 70 | 71 | /** 72 | * 查询需要重试的消息列表 73 | * 74 | * @return 75 | */ 76 | List queryRetryList(String unDead,Long timeout,String sending); 77 | 78 | List queryConfirmList(Long timeout, Integer maxconfirmtimes); 79 | 80 | Integer update(TransactionMessage message); 81 | } 82 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.task; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.distribute.common.utils.Constant; 5 | import com.distribute.message.domain.TransactionMessage; 6 | import com.distribute.service.TransactionMessageService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.scheduling.annotation.Scheduled; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by wly on 2018/8/31. 18 | */ 19 | @Component 20 | public class Task { 21 | private Logger log = LoggerFactory.getLogger( this.getClass() ); 22 | @Autowired 23 | private TransactionMessageService transactionMessageService; 24 | 25 | 26 | @Value("${retry.maxTimeOut}") 27 | private Long maxTimeOut; 28 | 29 | /** 30 | * 定时重发消息(每分钟) 31 | */ 32 | @Scheduled(cron = "0 */1 * * * ?") 33 | public void handler(){ 34 | //查询transaction_message表中已发送但未被删除的消息 35 | List list = transactionMessageService.queryRetryList( Constant.MESSAGE_UNDEAD, maxTimeOut, Constant.MESSAGE_SENDING ); 36 | if(list!=null && list.size() > 0){ 37 | for (TransactionMessage message:list){ 38 | try { 39 | transactionMessageService.retry( message.getMessageId() ); 40 | } catch (Exception e) { 41 | log.warn(">>> 消息不存在,可能已经被消费,消息编号:{}", message.getMessageId()); 42 | } 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * 定时通知工作人员(每隔5分钟) 49 | */ 50 | @Scheduled(cron = "0 */5 * * * ?") 51 | public void advance(){ 52 | List messages = transactionMessageService.queryDeadList(); 53 | log.warn(">>> 共有:{}条消息需要人工处理", messages.size()); 54 | String ids = JSONObject.toJSONString( messages ); 55 | //发邮件或者是发送短信通知工作人员处理 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/order/domain/Orders.java: -------------------------------------------------------------------------------- 1 | 2 | package com.distribute.order.domain; 3 | 4 | import com.distribute.OrderDetail; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.util.Date; 10 | import java.util.List; 11 | 12 | 13 | /** 14 | * 订单 15 | * Created by wly on 2018/8/22. 16 | */ 17 | @Entity 18 | public class Orders implements Serializable{ 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @Id 23 | @GeneratedValue(strategy= GenerationType.IDENTITY) 24 | private Long id; 25 | 26 | private Date createTime; 27 | 28 | private BigDecimal orderPrice; 29 | 30 | private Long buyerId; 31 | 32 | private String orderCode; 33 | 34 | private String payType; 35 | 36 | @Transient 37 | private List list; 38 | 39 | @Transient 40 | private String messageId; 41 | 42 | public Long getId() { 43 | return id; 44 | } 45 | 46 | public void setId(Long id) { 47 | this.id = id; 48 | } 49 | 50 | public Date getCreateTime() { 51 | return createTime; 52 | } 53 | 54 | public void setCreateTime(Date createTime) { 55 | this.createTime = createTime; 56 | } 57 | 58 | public BigDecimal getOrderPrice() { 59 | return orderPrice; 60 | } 61 | 62 | public void setOrderPrice(BigDecimal orderPrice) { 63 | this.orderPrice = orderPrice; 64 | } 65 | 66 | public Long getBuyerId() { 67 | return buyerId; 68 | } 69 | 70 | public void setBuyerId(Long buyerId) { 71 | this.buyerId = buyerId; 72 | } 73 | 74 | public String getOrderCode() { 75 | return orderCode; 76 | } 77 | 78 | public void setOrderCode(String orderCode) { 79 | this.orderCode = orderCode; 80 | } 81 | 82 | public String getPayType() { 83 | return payType; 84 | } 85 | 86 | public void setPayType(String payType) { 87 | this.payType = payType; 88 | } 89 | 90 | public List getList() { 91 | return list; 92 | } 93 | 94 | public void setList(List list) { 95 | this.list = list; 96 | } 97 | 98 | public String getMessageId() { 99 | return messageId; 100 | } 101 | 102 | public void setMessageId(String messageId) { 103 | this.messageId = messageId; 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/product/domain/Product.java: -------------------------------------------------------------------------------- 1 | package com.distribute.product.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.util.Date; 10 | 11 | /** 12 | * 商品 13 | * Created by wly on 2018/8/22. 14 | */ 15 | @Entity 16 | public class Product implements Serializable{ 17 | 18 | private static final long serialVersionUID = 1L; 19 | @Id 20 | @GeneratedValue(strategy= GenerationType.IDENTITY) 21 | private Long id; 22 | private String productName; 23 | private BigDecimal productPrice; 24 | private Long productSku; 25 | private String productSpec; 26 | private Date createTime;//上架时间 27 | private String remark; 28 | 29 | public Long getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Long id) { 34 | this.id = id; 35 | } 36 | 37 | public String getProductName() { 38 | return productName; 39 | } 40 | 41 | public void setProductName(String productName) { 42 | this.productName = productName; 43 | } 44 | 45 | public BigDecimal getProductPrice() { 46 | return productPrice; 47 | } 48 | 49 | public void setProductPrice(BigDecimal productPrice) { 50 | this.productPrice = productPrice; 51 | } 52 | 53 | public Long getProductSku() { 54 | return productSku; 55 | } 56 | 57 | public void setProductSku(Long productSku) { 58 | this.productSku = productSku; 59 | } 60 | 61 | public String getProductSpec() { 62 | return productSpec; 63 | } 64 | 65 | public void setProductSpec(String productSpec) { 66 | this.productSpec = productSpec; 67 | } 68 | 69 | public Date getCreateTime() { 70 | return createTime; 71 | } 72 | 73 | public void setCreateTime(Date createTime) { 74 | this.createTime = createTime; 75 | } 76 | 77 | public String getRemark() { 78 | return remark; 79 | } 80 | 81 | public void setRemark(String remark) { 82 | this.remark = remark; 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | return "Product{" + 88 | "id=" + id + 89 | ", productName='" + productName + '\'' + 90 | ", productPrice=" + productPrice + 91 | ", productSku=" + productSku + 92 | ", productSpec='" + productSpec + '\'' + 93 | ", createTime=" + createTime + 94 | ", remark='" + remark + '\'' + 95 | '}'; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.controller; 2 | 3 | import com.alibaba.dubbo.config.annotation.Reference; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.distribute.OrderDetail; 6 | import com.distribute.common.enums.ErrorCode; 7 | import com.distribute.order.domain.Orders; 8 | import com.distribute.product.domain.Product; 9 | import com.distribute.service.OrderService; 10 | import com.distribute.service.ProductService; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.math.BigDecimal; 16 | import java.util.*; 17 | 18 | /** 19 | * Created by wly on 2018/8/24. 20 | */ 21 | @Controller 22 | @RequestMapping("/") 23 | public class OrderController { 24 | @Autowired 25 | private OrderService orderService; 26 | 27 | @Reference 28 | private ProductService productService; 29 | 30 | /** 31 | * 创建订单 32 | * @return 33 | */ 34 | @RequestMapping(value = "/createOrder",method = RequestMethod.POST) 35 | @ResponseBody 36 | public Map createOrder(@RequestBody Map mp){ 37 | Object buyerId = mp.get( "buyerId" ); 38 | Object object = mp.get( "list" ); 39 | String jsonStr = JSONObject.toJSONString( object ); 40 | List list = JSONObject.parseArray( jsonStr, OrderDetail.class ); 41 | Map map = new HashMap<>( ); 42 | BigDecimal totalPrice = new BigDecimal( 0 ); 43 | if(list!=null && list.size() > 0){ 44 | for(OrderDetail p : list){ 45 | Product product = productService.findById( p.getId() ); 46 | if(product.getProductSku() < p.getNum()){ 47 | map.put( "reuslt",ErrorCode.LOW_STOCKS.getCode() ); 48 | return map; 49 | } 50 | BigDecimal price = product.getProductPrice().multiply(new BigDecimal( p.getNum() )); 51 | totalPrice = totalPrice.add( price ); 52 | p.setProduct( null ); 53 | } 54 | } 55 | Orders order = new Orders(); 56 | order.setBuyerId( Long.parseLong( buyerId.toString() ) ); 57 | order.setCreateTime( new Date( ) ); 58 | order.setOrderCode( UUID.randomUUID().toString() ); 59 | order.setOrderPrice( totalPrice ); 60 | order.setList( list ); 61 | order.setMessageId( UUID.randomUUID().toString() ); 62 | orderService.add( order ); 63 | map.put( "result",ErrorCode.SUCCESS.getCode() ); 64 | return map; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /order/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.distribute.order 7 | order 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | order 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.4.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-data-jpa 45 | 46 | 47 | mysql 48 | mysql-connector-java 49 | 50 | 51 | io.dubbo.springboot 52 | spring-boot-starter-dubbo 53 | 1.0.0 54 | 55 | 56 | com.101tec 57 | zkclient 58 | 0.3 59 | 60 | 61 | com.alibaba 62 | fastjson 63 | 1.2.46 64 | 65 | 66 | 67 | com.distribute.consis 68 | api-service 69 | 1.0-SNAPSHOT 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.springframework.boot 78 | spring-boot-maven-plugin 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /api-service/src/main/java/com/distribute/message/domain/TransactionMessage.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.io.Serializable; 8 | import java.util.Date; 9 | 10 | /** 11 | * 事务消息 12 | * Created by wly on 2018/8/22. 13 | */ 14 | @Entity 15 | public class TransactionMessage implements Serializable{ 16 | 17 | private static final long serialVersionUID = 1L; 18 | @Id 19 | @GeneratedValue(strategy= GenerationType.IDENTITY) 20 | private Long id; 21 | private Date createTime; 22 | private Date modifyTime; 23 | private String messageId; 24 | private String messageBody; 25 | private String queueName; 26 | private String status; 27 | private String remark; 28 | 29 | private Integer sendTimes = 0;//消息发送次数 30 | private String deadMessage = "0";//如果为1:需要人工处理的消息 0:如果超时未删除这进入重发消息任务 31 | 32 | 33 | 34 | public String getQueueName() { 35 | return queueName; 36 | } 37 | 38 | public void setQueueName(String queueName) { 39 | this.queueName = queueName; 40 | } 41 | 42 | public Long getId() { 43 | return id; 44 | } 45 | 46 | public void setId(Long id) { 47 | this.id = id; 48 | } 49 | 50 | public Date getCreateTime() { 51 | return createTime; 52 | } 53 | 54 | public void setCreateTime(Date createTime) { 55 | this.createTime = createTime; 56 | } 57 | 58 | public Date getModifyTime() { 59 | return modifyTime; 60 | } 61 | 62 | public void setModifyTime(Date modifyTime) { 63 | this.modifyTime = modifyTime; 64 | } 65 | 66 | public String getMessageId() { 67 | return messageId; 68 | } 69 | 70 | public void setMessageId(String messageId) { 71 | this.messageId = messageId; 72 | } 73 | 74 | public String getMessageBody() { 75 | return messageBody; 76 | } 77 | 78 | public void setMessageBody(String messageBody) { 79 | this.messageBody = messageBody; 80 | } 81 | 82 | 83 | public String getStatus() { 84 | return status; 85 | } 86 | 87 | public void setStatus(String status) { 88 | this.status = status; 89 | } 90 | 91 | public String getRemark() { 92 | return remark; 93 | } 94 | 95 | public void setRemark(String remark) { 96 | this.remark = remark; 97 | } 98 | 99 | public Integer getSendTimes() { 100 | return sendTimes; 101 | } 102 | 103 | public void setSendTimes(Integer sendTimes) { 104 | this.sendTimes = sendTimes; 105 | } 106 | 107 | public String getDeadMessage() { 108 | return deadMessage; 109 | } 110 | 111 | public void setDeadMessage(String deadMessage) { 112 | this.deadMessage = deadMessage; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /order/src/main/java/com/distribute/order/service/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.distribute.order.service.impl; 2 | 3 | import com.alibaba.dubbo.config.annotation.Reference; 4 | import com.alibaba.dubbo.config.annotation.Service; 5 | import com.alibaba.fastjson.JSONObject; 6 | import com.distribute.common.utils.Constant; 7 | import com.distribute.order.dao.OrderDao; 8 | import com.distribute.order.domain.Orders; 9 | import com.distribute.product.domain.Product; 10 | import com.distribute.service.OrderService; 11 | import com.distribute.service.ProductService; 12 | import com.distribute.service.TransactionMessageService; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.transaction.annotation.Transactional; 17 | 18 | /** 19 | * Created by wly on 2018/8/23. 20 | */ 21 | @Service 22 | public class OrderServiceImpl implements OrderService{ 23 | private final Logger log = LoggerFactory.getLogger( this.getClass() ); 24 | @Autowired 25 | private OrderDao orderDao; 26 | 27 | @Reference 28 | private TransactionMessageService transactionMessageService; 29 | 30 | @Reference 31 | private ProductService productService; 32 | 33 | @Override 34 | @Transactional 35 | public void add(Orders order) { 36 | String messageBody = JSONObject.toJSONString( order ); 37 | //添加消息到数据库 38 | String messageId = transactionMessageService.savePreparMessage(order.getMessageId(), messageBody, Constant.ORDER_QUEUE_NAME ); 39 | log.info(">>> 预发送消息,消息编号:{}", messageId); 40 | boolean flag = false; 41 | boolean success = false; 42 | try{ 43 | 44 | Orders orders = orderDao.saveAndFlush( order ); 45 | //int i = 1/0 ; 46 | log.info(">>> 插入订单,订单编号:{}", orders.getId()); 47 | flag = true; 48 | }catch (Exception e){ 49 | transactionMessageService.delete( messageId ); 50 | log.info(">>> 业务执行异常删除消息,消息编号:{}", messageId, e); 51 | throw new RuntimeException( ">>> 创建订单失败" ); 52 | }finally { 53 | if(flag){ 54 | try { 55 | transactionMessageService.confirmAndSend( messageId ); 56 | success = true; 57 | log.info(">>> 确认并且发送消息到实时消息中间件,消息编号:{}", messageId); 58 | 59 | }catch (Exception e){ 60 | log.error(">>> 消息确认异常,消息编号:{}", messageId, e); 61 | if(!success){ 62 | transactionMessageService.delete( messageId ); 63 | throw new RuntimeException( ">>> 确认消息异常,创建订单失败" ); 64 | } 65 | } 66 | } 67 | } 68 | } 69 | 70 | @Override 71 | public void delete(long id) { 72 | orderDao.deleteById( id ); 73 | } 74 | 75 | @Override 76 | public void update(Orders order) { 77 | orderDao.save( order ); 78 | } 79 | 80 | @Override 81 | public Orders findById(long id) { 82 | return orderDao.findById( id ); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /product/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.distribute.product 7 | product 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | product 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.4.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-activemq 46 | 47 | 48 | io.dubbo.springboot 49 | spring-boot-starter-dubbo 50 | 1.0.0 51 | 52 | 53 | com.101tec 54 | zkclient 55 | 0.3 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-data-jpa 60 | 61 | 62 | mysql 63 | mysql-connector-java 64 | 65 | 66 | com.alibaba 67 | fastjson 68 | 1.2.46 69 | 70 | 71 | 72 | com.distribute.consis 73 | api-service 74 | 1.0-SNAPSHOT 75 | 76 | 77 | 78 | 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-maven-plugin 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /product/src/main/java/com/distribute/product/service/impl/ProductConsumerListener.java: -------------------------------------------------------------------------------- 1 | package com.distribute.product.service.impl; 2 | 3 | import com.alibaba.dubbo.config.annotation.Reference; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.distribute.OrderDetail; 6 | import com.distribute.common.utils.Constant; 7 | import com.distribute.message.domain.DbLog; 8 | import com.distribute.message.domain.TransactionMessage; 9 | import com.distribute.order.domain.Orders; 10 | import com.distribute.product.domain.Product; 11 | import com.distribute.service.DbLogService; 12 | import com.distribute.service.ProductService; 13 | import com.distribute.service.TransactionMessageService; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.jms.annotation.JmsListener; 18 | import org.springframework.stereotype.Component; 19 | import org.springframework.transaction.annotation.Transactional; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * Created by wly on 2018/8/25. 25 | */ 26 | @Component 27 | public class ProductConsumerListener{ 28 | @Reference 29 | private TransactionMessageService transactionMessageService; 30 | @Reference 31 | private DbLogService dbLogService; 32 | @Autowired 33 | private ProductService productService; 34 | 35 | private final Logger log = LoggerFactory.getLogger( this.getClass() ); 36 | @Transactional 37 | @JmsListener( destination = Constant.ORDER_QUEUE_NAME) 38 | public void receiveQueue(String msg){ 39 | boolean flag = false; 40 | Orders orders = JSONObject.parseObject( msg, Orders.class ); 41 | log.info(">>> 接收到mq消息队列,消息编号:{} ,消息内容:{}", orders.getMessageId(), msg); 42 | 43 | TransactionMessage transactionMessage = transactionMessageService.findByMessageId( orders.getMessageId() ); 44 | try { 45 | //保证幂等性 46 | if(transactionMessage!=null){ 47 | List list = orders.getList(); 48 | for(OrderDetail detail : list){ 49 | Product product = productService.findById( detail.getId() ); 50 | Long skuNum = product.getProductSku() - detail.getNum(); 51 | if(skuNum >= 0){ 52 | product.setProductSku( skuNum ); 53 | productService.update( product ); 54 | }else { 55 | throw new Exception( ">>> 库存不足,修改库存失败!" ); 56 | } 57 | 58 | } 59 | //int i = 1 /0 ; 60 | flag = true; 61 | } 62 | 63 | }catch (Exception e){ 64 | e.printStackTrace(); 65 | throw new RuntimeException( e ); 66 | }finally { 67 | if(flag){ 68 | transactionMessageService.delete( orders.getMessageId() ); 69 | DbLog dbLog = dbLogService.findByMesageId( orders.getMessageId() ); 70 | if(dbLog!=null){ 71 | dbLog.setState( "1" );//已处理成功 72 | dbLogService.update( dbLog ); 73 | } 74 | log.info(">>> 业务执行成功删除消息! messageId:{}", orders.getMessageId()); 75 | } 76 | } 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /api-service/src/test/java/PostTest.java: -------------------------------------------------------------------------------- 1 | 2 | import com.alibaba.fastjson.JSONObject; 3 | import com.distribute.order.domain.OrderDetails; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.io.PrintWriter; 9 | import java.net.URL; 10 | import java.net.URLConnection; 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.concurrent.CountDownLatch; 16 | import java.util.concurrent.ExecutorService; 17 | import java.util.concurrent.Executors; 18 | 19 | /** 20 | * Created by wly on 2018/8/30. 21 | */ 22 | public class PostTest { 23 | public static void main(String[] args) { 24 | final List list = new ArrayList( ); 25 | final Map map = new HashMap( ); 26 | // 锁住所有线程,等待并发执行 27 | final CountDownLatch begin = new CountDownLatch(1); 28 | 29 | 30 | final ExecutorService exec = Executors.newFixedThreadPool(10); 31 | 32 | for (int index = 0; index < 10; index++) 33 | { 34 | final int NO = index + 1; 35 | 36 | Runnable run = new Runnable() 37 | { 38 | public void run() { 39 | try { 40 | // 等待,所有一起执行 41 | begin.await(); 42 | //开始模拟登录等待。。。 43 | System.out.println("No." + NO + " execute"); 44 | } catch (InterruptedException e) 45 | { 46 | e.printStackTrace(); 47 | } 48 | finally { 49 | } 50 | } 51 | }; 52 | exec.submit(run); 53 | } 54 | 55 | System.out.println("开始执行"); 56 | // begin减一,开始并发执行 57 | begin.countDown(); 58 | 59 | //关闭执行 60 | exec.shutdown(); 61 | } 62 | 63 | /** 64 | * 向指定 URL 发送POST方法的请求 65 | * 66 | * @param url 67 | * 发送请求的 URL 68 | * @param param 69 | * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 70 | * @return 所代表远程资源的响应结果 71 | */ 72 | public static String sendPost(String url, String param) { 73 | PrintWriter out = null; 74 | BufferedReader in = null; 75 | String result = ""; 76 | try { 77 | URL realUrl = new URL(url); 78 | // 打开和URL之间的连接 79 | URLConnection conn = realUrl.openConnection(); 80 | // 设置通用的请求属性 81 | conn.setRequestProperty("accept", "*/*"); 82 | conn.setRequestProperty("connection", "Keep-Alive"); 83 | conn.setRequestProperty("user-agent", 84 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 85 | // 发送POST请求必须设置如下两行 86 | conn.setDoOutput(true); 87 | conn.setDoInput(true); 88 | // 获取URLConnection对象对应的输出流 89 | out = new PrintWriter(conn.getOutputStream()); 90 | // 发送请求参数 91 | out.print(param); 92 | // flush输出流的缓冲 93 | out.flush(); 94 | // 定义BufferedReader输入流来读取URL的响应 95 | in = new BufferedReader( 96 | new InputStreamReader(conn.getInputStream())); 97 | String line; 98 | while ((line = in.readLine()) != null) { 99 | result += line; 100 | } 101 | } catch (Exception e) { 102 | System.out.println("发送 POST 请求出现异常!"+e); 103 | e.printStackTrace(); 104 | } 105 | //使用finally块来关闭输出流、输入流 106 | finally{ 107 | try{ 108 | if(out!=null){ 109 | out.close(); 110 | } 111 | if(in!=null){ 112 | in.close(); 113 | } 114 | } 115 | catch(IOException ex){ 116 | ex.printStackTrace(); 117 | } 118 | } 119 | return result; 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /message/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.distribute.message 7 | message 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | message 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.4.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | org.apache.logging.log4j 38 | log4j-to-slf4j 39 | 40 | 41 | 42 | 43 | org.slf4j 44 | slf4j-api 45 | 1.7.25 46 | 47 | 48 | org.slf4j 49 | log4j-over-slf4j 50 | 51 | 52 | org.slf4j 53 | jcl-over-slf4j 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-test 58 | test 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-activemq 63 | 64 | 65 | io.dubbo.springboot 66 | spring-boot-starter-dubbo 67 | 1.0.0 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-starter-data-jpa 73 | 74 | 75 | mysql 76 | mysql-connector-java 77 | 78 | 79 | com.101tec 80 | zkclient 81 | 0.3 82 | 83 | 84 | com.alibaba 85 | fastjson 86 | 1.2.46 87 | 88 | 89 | 90 | com.distribute.consis 91 | api-service 92 | 1.0-SNAPSHOT 93 | 94 | 95 | 96 | 97 | 98 | 99 | org.springframework.boot 100 | spring-boot-maven-plugin 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /message/src/main/java/com/distribute/message/service/impl/TransactionMessageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.distribute.message.service.impl; 2 | 3 | import com.alibaba.dubbo.config.annotation.Service; 4 | import com.distribute.common.enums.MessageStatus; 5 | import com.distribute.common.utils.Constant; 6 | import com.distribute.message.dao.DbLogDao; 7 | import com.distribute.message.dao.TransactionMessageDao; 8 | import com.distribute.message.domain.DbLog; 9 | import com.distribute.message.domain.TransactionMessage; 10 | import com.distribute.service.MessageQueueService; 11 | import com.distribute.service.TransactionMessageService; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.beans.factory.annotation.Value; 16 | 17 | import java.util.Date; 18 | import java.util.List; 19 | 20 | /** 21 | * Created by wly on 2018/8/23. 22 | */ 23 | @Service 24 | public class TransactionMessageServiceImpl implements TransactionMessageService { 25 | private static final Logger log = LoggerFactory.getLogger( TransactionMessageServiceImpl.class ); 26 | @Autowired 27 | private TransactionMessageDao transactionMessageDao; 28 | 29 | @Autowired 30 | private MessageQueueService messageQueueService; 31 | 32 | @Autowired 33 | private DbLogDao dbLogDao; 34 | 35 | @Value("${retry.maxsendtimes}") 36 | private Integer maxSendTimes; 37 | 38 | @Override 39 | public String savePreparMessage(String messageId,String messageBody, String consumerQueue) { 40 | TransactionMessage transactionMessage = new TransactionMessage(); 41 | transactionMessage.setCreateTime( new Date( ) ); 42 | transactionMessage.setMessageBody( messageBody ); 43 | transactionMessage.setQueueName( consumerQueue ); 44 | transactionMessage.setStatus( MessageStatus.WAITING_CONFIRM.getKey() ); 45 | transactionMessage.setMessageId( messageId ); 46 | transactionMessageDao.save( transactionMessage ); 47 | return messageId; 48 | } 49 | 50 | @Override 51 | public void confirmAndSend(String messageId) throws Exception { 52 | //int i = 1/0; 53 | TransactionMessage transactionMessage = messageExist( messageId ); 54 | if(!MessageStatus.WAITING_CONFIRM.getKey().equals( transactionMessage.getStatus() )){ 55 | return; 56 | } 57 | transactionMessage.setStatus( MessageStatus.SENDING.getKey() ); 58 | transactionMessage.setModifyTime( new Date( ) ); 59 | transactionMessageDao.save( transactionMessage ); 60 | messageQueueService.sendMessageToMessageQueue( transactionMessage.getQueueName(),transactionMessage.getMessageBody() ); 61 | log.info(">>> 确认消息并且发送到消息中间件! 消息编号:{},队列名称:{}", messageId, transactionMessage.getQueueName()); 62 | 63 | } 64 | 65 | @Override 66 | public void directSendMessage(String messageBody, String consumerQueue) { 67 | messageQueueService.sendMessageToMessageQueue( consumerQueue,messageBody ); 68 | log.info(">>> 直接发送到消息中间件! 队列名称:{}", consumerQueue); 69 | } 70 | 71 | @Override 72 | public void retry(String messageId) throws Exception { 73 | TransactionMessage message = messageExist( messageId ); 74 | reSendMessage(message); 75 | } 76 | 77 | @Override 78 | public void delete(String messageId) { 79 | transactionMessageDao.deleteByMessageId(messageId); 80 | } 81 | 82 | @Override 83 | public List queryRetryList() { 84 | return transactionMessageDao.findAll( ); 85 | } 86 | 87 | @Override 88 | public List queryDeadList() { 89 | return transactionMessageDao.queryDeadList(); 90 | } 91 | 92 | @Override 93 | public TransactionMessage findByMessageId(String messageId) { 94 | return transactionMessageDao.findByMessageId( messageId ); 95 | } 96 | 97 | /** 98 | * 查询已发送、超时未删除且未死亡的消息 99 | * @param timeout 100 | * @return 101 | */ 102 | @Override 103 | public List queryRetryList(String unDead,Long timeout,String sending) { 104 | return transactionMessageDao.queryRetryList( unDead,timeout,sending ); 105 | } 106 | 107 | @Override 108 | public List queryConfirmList(Long timeout, Integer maxconfirmtimes) { 109 | return null; 110 | } 111 | 112 | @Override 113 | public Integer update(TransactionMessage message) { 114 | transactionMessageDao.save( message ); 115 | return 1; 116 | } 117 | 118 | /** 119 | * 验证messageId是否存在 120 | * 121 | * @param messageId 122 | */ 123 | private TransactionMessage messageExist(String messageId) throws Exception { 124 | TransactionMessage message = transactionMessageDao.findByMessageId(messageId); 125 | if (message == null) { 126 | throw new Exception(String.format("消息编号%s不存在", messageId)); 127 | } 128 | return message; 129 | } 130 | 131 | /** 132 | * 重新发送消息 133 | * @param message 134 | */ 135 | private void reSendMessage(TransactionMessage message) { 136 | message.setSendTimes( message.getSendTimes() + 1 ); 137 | if(message.getSendTimes() >= maxSendTimes){ 138 | //验证次数大于等于最大尝试次数 139 | message.setDeadMessage( "1" ); 140 | transactionMessageDao.save( message ); 141 | DbLog dbLog = new DbLog(); 142 | dbLog.setCreateTime( new Date( ) ); 143 | dbLog.setMessageId( message.getMessageId() ); 144 | dbLog.setState( "0" );//等待人工处理 145 | dbLogDao.save( dbLog ); 146 | log.info(">>> 消息超出最大重试次数标识死亡!消息编号:{},重试次数:{}", message.getMessageId(), message.getSendTimes()); 147 | }else { 148 | transactionMessageDao.save( message ); 149 | messageQueueService.sendMessageToMessageQueue( message.getQueueName(),message.getMessageBody() ); 150 | log.info(">>> 重新发送消息! 消息编号:{}", message.getMessageId()); 151 | } 152 | 153 | 154 | 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /order/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /message/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /product/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /message/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /order/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /product/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------